RSACryptoServiceProvider KeyContainer appears to time out?
I am using the RSACryptoServiceProvider like this...
private byte[] RSAEncrypt(byte[] DataToEncrypt, string ContainerName, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
// Create a new instance of CspParameters. Pass
// 13 to specify a DSA container or 1 to specify
// an RSA container. The default is 1.
CspParameters cspParams = new CspParameters();
// Specify the container name using the passed variable.
cspParams.KeyContainerName = ContainerName;
cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams))
{
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}
return encryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException ex)
{
sl.Write(ex, Messa开发者_JAVA技巧geType.Error);
throw;
}
}
I then try to decrypt the data after turning off my Outlook Plugin Windows Form application and turning it back on which is what is using this peice of code. The decrypt code looks like this...
private byte[] RSAEncrypt(byte[] DataToEncrypt, string ContainerName, bool DoOAEPPadding)
{
try
{
byte[] encryptedData;
// Create a new instance of CspParameters. Pass
// 13 to specify a DSA container or 1 to specify
// an RSA container. The default is 1.
CspParameters cspParams = new CspParameters();
// Specify the container name using the passed variable.
cspParams.KeyContainerName = ContainerName;
cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cspParams))
{
//Encrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}
return encryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException ex)
{
sl.Write(ex, MessageType.Error);
throw;
}
}
Works great until something comes up that I can not put my finger on. I don't know if it is like the date changes or what. What happens is that I try to decrypt the data and I get a "bad data" error. Now again it works great until some elapsed period of time, or turning off the app, or the user logging off. I just don't know and can't determine what causes it. The moment I blow away the encrypted data which comes from a text file and recreate it and decrypt it I have no problem. Even if I restart the application in between encrypting/saving to file and the reading from file/decrypting it will works great! Something happens and I just don't know KeyContainers well enough to understand what could possibly make the CspParameters expire is my best guess?
You could try using the bouncy castle crypto libraries if you're really stuck:
http://www.bouncycastle.org/csharp/
I ended up using the CspParameters flag and instead of using the Users KeyContainer store I used the Machine KeyContainer Store.
Yes, if you set: cspParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
then the key container is stored in the user's key container store, then logging on as another user will and using RSA with present you with an entirely different KeyContainer store.
Using this instead: cspParams.Flags = CspProviderFlags.UseMachineKeyStore = true;
Will use the local machine's KeyContainer store, which is global for the machine, and will provide you with the same KeyContainer store, irregardless of which user is logged in. However, this only applies for that windows installation. Running your program under a different windows installation or machine will provide you with a different KeyContainer store. If you wish to decrypt the same data across multiple machines, you will need to persist your key to a file on the hard drive. Persisting a key to a plain text file is a huge security risk, so please encrypt your key before persisting it to a file, or put it in a password protected .rar files or something.
If your still having issues, try setting: RSA.PersistKeyInCsp = true;
This will ensure that your key is persisted in the KeyContainer store. Persisting the file in the KeyContainer should be the default behavior if you use the CspParameters constructor such as:
CspParameters cspParams = new CspParameters();
In Microsoft's own words: "This form of CspParameters initializes the ProviderType field to a value of 24, which specifies the PROV_RSA_AES provider." Source: http://msdn.microsoft.com/en-us/library/xw9ywed4.aspx
So your comments in your code is incorrect and my be misleading you. I would advise you to correct them.
I am unsure about other ProviderTypes and their default settings regarding persisting the key in the KeyContainer store, so setting PersistKeyInCsp to TRUE might be necessary if your still having issues.
Hope this helps.
~Adam WhiteHat();
精彩评论