【发布时间】:2017-11-22 15:51:11
【问题描述】:
我有一个有效的 RSA 加密,基本上是这样创建的
public string DecryptFormula( byte[] WholeData )
{
// Get from container the key used to encrypt entropy bytes
RSAParameters PublicKey = GetKeyFromContainer("CorroredKeys");
byte[] KeyLengthByte = new byte[4];
Array.Copy(WholeData, KeyLengthByte, 4);
int KeyLength = BitConverter.ToInt32(KeyLengthByte, 0);
// Encrypt entropy
byte[] encryptedKey = new byte[KeyLength];
Array.Copy(WholeData, 4, encryptedKey, 0, KeyLength);
//Pass the data to ENCRYPT, the public key information
//(using RSACryptoServiceProvider.ExportParameters(false),
//and a boolean flag specifying no OAEP padding.
byte[] PrivateKey = RSADecrypt(encryptedKey, PublicKey, false);
...
}
static public byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
{
try
{
byte[] decryptedData;
//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{
//Import the RSA Key information. This needs
//to include the private key information.
RSA.ImportParameters(RSAKeyInfo);
//Decrypt the passed byte array and specify OAEP padding.
//OAEP padding is only available on Microsoft Windows XP or
//later.
decryptedData = RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
}
return decryptedData;
}
//Catch and display a CryptographicException
//to the console.
catch (CryptographicException ex)
{
return null;
}
}
但是,在将运行此代码的服务器加入到域后,解密突然停止工作。到目前为止,我已经对此进行了调试,发现问题似乎出在
RSA.Decrypt(DataToDecrypt, DoOAEPPadding)
给出一个例外
System.Security.Cryptography.CryptographicException:参数不正确。
在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时)
在 System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle pKeyContext, Byte[] pbEncryptedKey, Int32 cbEncryptedKey, Boolean fOAEP, ObjectHandleOnStack ohRetDecryptedKey)
在 System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
在 MyCalculation.ProjectBase.RSADecrypt(Byte[] DataToDecrypt, RSAParameters RSAKeyInfo, Boolean DoOAEPPadding)
如何进行此操作以及在哪里寻找可能的原因?注意:此代码在服务器加入域之前运行。
编辑: Alex K. 询问我使用的密钥容器是否为空。这也是我怀疑的。但是,至少我的公钥的 Modulus 字段有一些数据。我无法在生产环境中运行调试器,但我编写了一些将字节数组写入日志文件的代码。
RSAParameters PublicKey = GetKeyFromContainer("CorroredKeys");
WriteLog("PublicKey, modulus: " + BytesToString(PublicKey.Modulus));
仅供参考,公钥是这样生成的:
public static RSAParameters GenKey_SaveInContainer(string ContainerName)
{
// First, to get a fresh key, delete the key from the container.
DeleteKeyFromContainer(ContainerName);
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container MyKeyContainerName and generates new public and private key data
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp))
{
byte[] Keyblob = RSA.ExportCspBlob(true);
// Return saved key information to the caller
return RSA.ExportParameters(false);
}
}
/// <summary>
/// Clears and deletes an asymmetric key pair from given key container
/// </summary>
/// <param name="ContainerName">Key container name where RSA key pair is saved</param>
public static void DeleteKeyFromContainer(string ContainerName)
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
// Delete the key entry in the container.
rsa.PersistKeyInCsp = false;
// Call Clear to release resources and delete the key from the container.
rsa.Clear();
}
这样从容器中读取密钥:
public static RSAParameters GetKeyFromContainer(string ContainerName)
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container MyKeyContainerName.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(cp))
{
// Return saved key information to the caller
return RSA.ExportParameters(true);
}
}
【问题讨论】:
-
如果您使用用户级密钥容器并以域用户身份登录,那么您将拥有不同的配置文件,因此您将拥有不同的(空)密钥容器,是这种情况吗?
标签: c# encryption cryptography rsa