System.Security.Cryptography.CryptographicException:keyset不存在

时间:2012-08-24 08:49:25

标签: c# x509certificate

当我将x509证书发送到encypt和decypt消息时,我收到了一些错误信息,无法解决此问题。有人会发生什么事来解决这个错误吗?感谢。

描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:

  

System.Security.Cryptography.CryptographicException:keyset不存在。

     

来源错误:

     

第53行:使用(RSACryptoServiceProvider   rsaProviderDecrypt =   (RSACryptoServiceProvider)cerDecrypt.PublicKey.Key)第54行:
  {第55行:plainHashBytes =   rsaProviderDecrypt.Decrypt(encryptedHashBytes,false);第56行:
  rsaProviderDecrypt.Clear();第57行:
  rsaProviderDecrypt.Dispose();

     

源文件:   E:\ PayUSite \ PayMvcApp \ Controllers \ HashMessageController.cs行:55

     

堆栈追踪:

     

[CryptographicException:keyset不存在。 ]
  System.Security.Cryptography.CryptographicException.ThrowCryptographicException(的Int32   hr)+41
  System.Security.Cryptography.RSACryptoServiceProvider.DecryptKey(SafeKeyHandle   pKeyContext,Byte [] pbEncryptedKey,Int32 cbEncryptedKey,Boolean   fOAEP,ObjectHandleOnStack ohRetDecryptedKey)+0
  System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(字节[]   rgb,布尔fOAEP)+579

源代码:

string docFile = Server.MapPath("~/docx/DirectAccess_StepByStep.doc");
HashAlgorithm hash = HashAlgorithm.Create("SHA1");
byte[] hashedBytes;
using (FileStream fs = new FileStream(docFile, FileMode.Open))
{
    //compute message hash value
    hashedBytes = hash.ComputeHash(fs);
    hash.Dispose();
    fs.Close();
}

string hashedString = Convert.ToBase64String(hashedBytes);

//encrypt message digest
string priKeyFile = Server.MapPath("~/certificate/WosMiddle.pfx");
X509Certificate2 certEncrypt = new X509Certificate2(priKeyFile, "123456");
byte[] encryptedHashBytes;
using (RSACryptoServiceProvider rsaProviderEncrypt = (RSACryptoServiceProvider)certEncrypt.PrivateKey)
{
    encryptedHashBytes = rsaProviderEncrypt.Encrypt(hashedBytes, false);
    rsaProviderEncrypt.Dispose();
}

//decrypt message digest
string pubKeyFile = Server.MapPath("~/certificate/WosMiddle-pubkey.cer");
X509Certificate2 cerDecrypt = new X509Certificate2(pubKeyFile);
byte[] plainHashBytes;
using (RSACryptoServiceProvider rsaProviderDecrypt = (RSACryptoServiceProvider)cerDecrypt.PublicKey.Key)
{
    //***will throw error message here...***
    plainHashBytes = rsaProviderDecrypt.Decrypt(encryptedHashBytes, false);
    rsaProviderDecrypt.Dispose();
}

//verify message whether was modified
string docFile2 = Server.MapPath("~/docx/DirectAccess_StepByStep.doc");
HashAlgorithm hash2 = HashAlgorithm.Create("SHA1");
byte[] hashedBytes2;
using (FileStream fs2 = new FileStream(docFile2, FileMode.Open))
{
    //compute message hash value
    hashedBytes2 = hash.ComputeHash(fs2);
    fs2.Close();
}

//compare hash value
bool isEqual = plainHashBytes.SequenceEqual(hashedBytes2);

8 个答案:

答案 0 :(得分:96)

这个问题很老,但是对于那些在继续使用EncryptDecrypt的同时寻找解决方案的人来说,我是如何设法解决此错误的:

通过双击.pfx文件并选择商店,基础是我的证书安装错误。

安装证书的错误方法

1。双击证书:

certificate file

2. 向导打开,单击下一步按钮:

wizard 0

3. 向导显示证书位置,单击下一步按钮:

wizard 1

4. 输入密码,然后点击下一步:

wizard 2

5. 选择商店,然后点击下一步:

wizard 3

6. 向导显示证书信息,单击完成按钮

wizard 4

7。显示Succes对话框:

wizard 5

所以此时我的错误“Keyset不存在”


为了解决这个问题,我采用了这种方式(正确的方式)

1。执行Microsoft管理控制台(mmc.exe):

execute mmc

2. 一个空白的MMC实例显示:

mmc showed

3. 点击文件 - >添加/删除管理单元...

add snap-in

4. 添加按钮中单击选择证书管理单元:

add certificate snap-in

5. 选择 计算机帐户 ,然后点击下一步按钮:

select computer account

6. 选择 本地计算机 ,然后点击完成按钮:

selecct local computer

7。现在添加了证书管理单元,点击确定按钮:

certificate snap-in shows

8。选择个人商店,然后右键单击并选择导入

select personal store and import

9. 浏览证书,然后点击下一步:

browse certificate

10. 输入密码,然后点击下一步按钮:

enter image description here

11. 自动选择证书存储:

automatically select the store

12。证书信息显示:

certificate information

13. 成功对话框消息显示:

enter image description here

14. 刷新MMConsole以显示证书:

refresh mmc

15。右键单击证书,然后单击管理私钥......

manage private keys

16。在我添加IIS_IUSRS的情况下添加池标识或IIS用户:

add iis_iusrs

17。用户已添加,点击确定按钮:

user added

现在完成存在的键集!!

答案 1 :(得分:5)

应用程序可能正在尝试写入以下文件夹路径:C:\ Documents and Settings \ All Users \ Application Data \ Microsoft \ Crypto \ RSA \ MachineKeys

如果您的应用程序使用模拟或使用IUSR_MACHINENAME用户,则配置MachineKeys文件夹sercurities并向用户提供Read&执行,列出文件夹内容,读取,写入。如果这不起作用,请尝试为Everyone用户授予相同的权限。

答案 2 :(得分:3)

我相信在使用Encrypt和Decrypt时,它需要一个用于加密的公钥和一个用于解密的私钥。所以它失败了,因为你试图在没有私钥的情况下进行解密并导致异常。

你应该真的在使用 用于创建签名的SignData方法和用于验证的VerifyData

答案 3 :(得分:2)

我确实遇到了同样的问题。该消息并不理想,在我的情况下,我的用户没有访问私钥的权限。您可以使用以下步骤解决此问题:

  1. 打开mmc
  2. 添加证书管理单元
  3. 选择要使用的证书
  4. 右键单击它,然后选择“所有任务” /“管理私钥...”
  5. 将您的用户添加到授权用户列表中,并允许“完全控制”

答案 4 :(得分:2)

尝试以管理员身份运行。为我工作

答案 5 :(得分:1)

当我在尝试签署SAML响应时未将我的证书中的PrivateKey加载到我的signedXmlElement的SigningKey中时,我遇到了此错误。

signedElement.SigningKey = myCertificate.PrivateKey;

答案 6 :(得分:0)

我收到与OP相同的错误: “System.Security.Cryptography.CryptographicException:keyset不存在”

决议(对我而言)是: Visual Studio需要(以管理员身份运行)

正如向我(YMMV)解释的那样,VS需要作为Admin运行才能从密钥库中提取证书私钥,以便与keyvault协商auth / handshake。

答案 7 :(得分:0)

在我的情况下,私钥存储在"C:\ProgramData\Microsoft\Crypto\Keys"中,而不是machinekeys文件夹中-您可以使用certutil进行检查,以找出将成为私钥的“唯一容器名称”。

我现在浏览加密目录以找到匹配项。通过匹配,我可以在适当的文件上设置正确的ACL