CryptographicException"关键不适于在指定状态下使用&QUOT。而试图导出X509私钥RSAParameters关键、状态下、QUOT、CryptographicExce

2023-09-03 05:40:14 作者:影子是时光的心

我盯着这个相当长的一段时间,感谢MSDN文档我真的不能弄清楚发生了什么事情。基本上我加载从盘一个PFX文件转换成 X509Certificate2 并尝试使用公共密钥字符串加密和解密使用私钥。

I am staring at this for quite a while and thanks to the MSDN documentation I cannot really figure out what's going. Basically I am loading a PFX file from the disc into a X509Certificate2 and trying to encrypt a string using the public key and decrypt using the private key.

为什么我不解:加密/解密的工作时,我通过引用的RSACryptoServiceProvider 本身:

Why am I puzzled: the encryption/decryption works when I pass the reference to the RSACryptoServiceProvider itself:

byte[] ed1 = EncryptRSA("foo1", x.PublicKey.Key as RSACryptoServiceProvider);
string foo1 = DecryptRSA(ed1, x.PrivateKey as RSACryptoServiceProvider);

但如果出口,并通过周围的 RSAParameter

byte[] ed = EncryptRSA("foo", (x.PublicKey.Key as RSACryptoServiceProvider).ExportParameters(false));
string foo = DecryptRSA(ed, (x.PrivateKey as RSACryptoServiceProvider).ExportParameters(true));

...它抛出一个键不适于在指定状态下使用。除了试图导出私钥 RSAParameter 。请注意,PFX从标记导出生成的证书(即我所用的PE标志,同时创造了证书)。任何想法是什么原因造成的例外呢?

...it throws a "Key not valid for use in specified state." exception while trying to export the private key to RSAParameter. Please note that the cert the PFX is generated from is marked exportable (i.e. I used the pe flag while creating the cert). Any idea what is causing the exception?

 static void Main(string[] args)
    {
        X509Certificate2 x = new X509Certificate2(@"C:\temp\certs\1\test.pfx", "test");
        x.FriendlyName = "My test Cert";

        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadWrite);
        try
        {
            store.Add(x);
        }
        finally
        {
            store.Close();
        }

        byte[] ed1 = EncryptRSA("foo1", x.PublicKey.Key as RSACryptoServiceProvider);
        string foo1 = DecryptRSA(ed1, x.PrivateKey as RSACryptoServiceProvider);

        byte[] ed = EncryptRSA("foo", (x.PublicKey.Key as RSACryptoServiceProvider).ExportParameters(false));
        string foo = DecryptRSA(ed, (x.PrivateKey as RSACryptoServiceProvider).ExportParameters(true));
    }

private static byte[] EncryptRSA(string data, RSAParameters rsaParameters)
{
    UnicodeEncoding bytConvertor = new UnicodeEncoding();
    byte[] plainData = bytConvertor.GetBytes(data);

    RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
    publicKey.ImportParameters(rsaParameters);
    return publicKey.Encrypt(plainData, true);
}

private static string DecryptRSA(byte[] data, RSAParameters rsaParameters)
{
    UnicodeEncoding bytConvertor = new UnicodeEncoding();

    RSACryptoServiceProvider privateKey = new RSACryptoServiceProvider();
    privateKey.ImportParameters(rsaParameters);

    byte[] deData = privateKey.Decrypt(data, true);
    return bytConvertor.GetString(deData);
}

private static byte[] EncryptRSA(string data, RSACryptoServiceProvider publicKey)
{
    UnicodeEncoding bytConvertor = new UnicodeEncoding();
    byte[] plainData = bytConvertor.GetBytes(data);

    return publicKey.Encrypt(plainData, true);
}

private static string DecryptRSA(byte[] data, RSACryptoServiceProvider privateKey)
{
    UnicodeEncoding bytConvertor = new UnicodeEncoding();

    byte[] deData = privateKey.Decrypt(data, true);
    return bytConvertor.GetString(deData);
}

只是在code以上的加粗部分澄清抛出: 字符串富= DecryptRSA(ED,(x.PrivateKey为的RSACryptoServiceProvider)** ExportParameters(真)**。);

Just to clarify in the code above the bold part is throwing: string foo = DecryptRSA(ed, (x.PrivateKey as RSACryptoServiceProvider)**.ExportParameters(true)**);

推荐答案

我认为这个问题可能是,关键是没有标记为可导出。还有另外一个构造 X509Certificate2 接受一个X509KeyStorageFlags枚举。尝试更换行:

I believe that the issue may be that the key is not marked as exportable. There is another constructor for X509Certificate2 that takes an X509KeyStorageFlags enum. Try replacing the line:

X509Certificate2 x = new X509Certificate2(@"C:\temp\certs\1\test.pfx", "test");

通过这样的:

X509Certificate2 x = new X509Certificate2(@"C:\temp\certs\1\test.pfx", "test", X509KeyStorageFlags.Exportable);