Lo sto fissando da un po 'e grazie allo MSDN documentation non riesco davvero a capire cosa sta succedendo. Fondamentalmente sto caricando un file PFX dal disco in un X509Certificate2
e provando a criptare una stringa usando la chiave pubblica e decifrare usando la chiave privata.CryptographicException "Chiave non valida per l'uso nello stato specificato." mentre provo ad esportare RSAParameters di una chiave privata X509
Perché io sono perplesso: la cifratura/decifratura funziona quando passo il riferimento alla RSACryptoServiceProvider
stesso:
byte[] ed1 = EncryptRSA("foo1", x.PublicKey.Key as RSACryptoServiceProvider);
string foo1 = DecryptRSA(ed1, x.PrivateKey as RSACryptoServiceProvider);
Ma se l'esportazione e passare tutto il RSAParameter
:
byte[] ed = EncryptRSA("foo", (x.PublicKey.Key as RSACryptoServiceProvider).ExportParameters(false));
string foo = DecryptRSA(ed, (x.PrivateKey as RSACryptoServiceProvider).ExportParameters(true));
.. .it lancia una "Chiave non valida per l'uso nello stato specificato". eccezione durante il tentativo di esportare la chiave privata a RSAParameter
. Si noti che il certificato generato da PFX è contrassegnato come esportabile (ad esempio, ho usato il flag pe durante la creazione del certificato). Qualche idea su cosa sta causando l'eccezione?
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);
}
Giusto per chiarire nel codice qui sopra la parte in grassetto sta gettando: string foo = DecryptRSA(ed, (x.PrivateKey as RSACryptoServiceProvider)**.ExportParameters(true)**);
Scusate se non mi sono chiarito molto bene, posso rompere questa linea: stringa foo = DecryptRSA (a cura di, (x.PrivateKey come RSACryptoServiceProvider) .ExportParameters (veri)); in: var pvk = (x.PrivateKey come RSACryptoServiceProvider); var pvkParam = pvk.ExportParameters (true); string foo = DecryptRSA (ed, pvkParam); ... e se lo faccio pvk.ExportParameters (true); getterà. – kalrashi
Questo errore è uno degli errori più fastidiosi mai scritti. Può significare tante cose. Per me è stato come ha detto Jeroen: il mio messaggio era troppo grande per essere crittografato dalla chiave (è il lato negativo della crittografia asincrona). – Aejay