C# System.Security.Cryptography.CryptographicException:密钥集不存在
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12106011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
System.Security.Cryptography.CryptographicException: keyset does not exist
提问by Bes Ley
When I make x509 certificate to encypt and decypt message, I got some error information and could not fix this problem. Could someone ever happend to solve this bug? thanks.
当我将 x509 证书制作为 encypt 和 decypt 消息时,我收到了一些错误信息,无法解决此问题。有人碰巧解决了这个错误吗?谢谢。
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。
Exception Details:
异常详情:
System.Security.Cryptography.CryptographicException: keyset does not exist。
Source Error:
Line 53: using (RSACryptoServiceProvider rsaProviderDecrypt = (RSACryptoServiceProvider)cerDecrypt.PublicKey.Key) Line 54:
{ Line 55: plainHashBytes = rsaProviderDecrypt.Decrypt(encryptedHashBytes, false); Line 56:
rsaProviderDecrypt.Clear(); Line 57:
rsaProviderDecrypt.Dispose();Source File: E:\PayUSite\PayMvcApp\Controllers\HashMessageController.cs Line: 55
Stack Trace:
[CryptographicException: keyset does not exist. ]
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(Byte[] rgb, Boolean fOAEP) +579
System.Security.Cryptography.CryptographicException: 密钥集不存在。
源错误:
第 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
堆栈跟踪:
[加密异常:密钥集不存在。]
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.DecryptKey .RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP) +579
source code:
源代码:
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);
回答by eMi
The application might be trying to write to the following folder path: C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
应用程序可能正在尝试写入以下文件夹路径:C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
If your application is using impersonation or using the IUSR_MACHINENAME user, then configure the MachineKeys folder sercurities and give the user Read & Execute, List Folder Contents, Read, Write. If that doesn't work, try giving the Everyone user the same permissions.
如果您的应用程序使用模拟或使用 IUSR_MACHINENAME 用户,则配置 MachineKeys 文件夹 sercurities 并为用户提供读取和执行、列出文件夹内容、读取、写入。如果这不起作用,请尝试为 Everyone 用户授予相同的权限。
回答by tyranid
I believe when using Encrypt and Decrypt it expects a public key for encrypt and a private key for decrypt. So it is failing because you are trying to decrypt without the private key and that causes the exception.
我相信在使用 Encrypt 和 Decrypt 时,它需要一个用于加密的公钥和一个用于解密的私钥。所以它失败了,因为你试图在没有私钥的情况下解密,这导致了异常。
You should really be using SignDatamethod for creating the signature and VerifyDatafor the verification.
您确实应该使用 SignData方法来创建签名并使用VerifyData进行验证。
回答by sabotero
This question is old but for someone looking for the solution while continuing to use Encryptand Decrypthere is how I manage to solve this error:
这个问题很老,但对于在继续使用的同时寻找解决方案的人来说Encrypt,Decrypt这是我设法解决此错误的方法:
The base is my certificate have been installed the wrong way by double-clicking the .pfxfile and selecting the store.
基础是我的证书已通过双击.pfx文件并选择商店以错误的方式安装。
The wrong way to install the certificate
安装证书的错误方法
1.Double click the certificate:
1.双击证书:


2.The wizard opens, click in the next button:
2.向导打开,点击下一步按钮:


3.The wizard show the certificates location, click in the next button:
3.向导显示证书位置,单击下一步按钮:


4.Enter the password then click next:
4.输入密码然后点击下一步:


5.Select the store then click next:
5.选择商店,然后单击下一步:


6.The wizard show the certificate information, click in Finishbutton
6.向导显示证书信息,点击完成按钮


7.Succes dialog is showed:
7.显示成功对话框:


So at this point I had the error "Keyset does not exist".
所以在这一点上我有错误"Keyset does not exist"。
To solve that I proceeded this way (the correct way)
为了解决这个问题,我是这样做的(正确的方法)
1.Execute Microsoft Management Console (mmc.exe):
1.执行微软管理控制台(mmc.exe):


2.A blank MMC instance showed:
2.一个空白的MMC实例显示:


3.Click in File->Add/Remove Snap-in...
3.单击文件->添加/删除管理单元...


4.Select certificate snap-in an click in Addbutton:
4.选择证书管理单元并单击添加按钮:


5.Select Computer accountthen click in Nextbutton:
5.选择计算机帐户,然后单击下一步按钮:


6.Select Local computerthen click in Finishbutton:
6.选择本地计算机,然后单击完成按钮:


7.The certificate snap-in is now added, click in OKbutton:
7.现在添加了证书管理单元,点击确定按钮:


8.Select the personal store, then right click and select Import:
8.选择个人商店,然后右键单击并选择导入:


9.Browse the certificate, and click next:
9.浏览证书,点击下一步:


10.Enter the password, then click in Nextbutton:
10.输入密码,然后点击下一步按钮:


11.Automatically select the certificate store:
11.自动选择证书库:


12.The certificate information shows:
12、证书信息显示:


13.Success dialog message shows:
13.成功对话框信息显示:


14.Refresh the MMConsole to show the certificate:
14.刷新 MMConsole 以显示证书:


15.Right click on the certificate, then click in Manage Private Keys...:
15.右键单击证书,然后单击Manage Private Keys...:


16.Add the pool identity or the IIS user in my case I added IIS_IUSRS:
16.添加池标识或 IIS 用户,在我添加 IIS_IUSRS 的情况下:


17.The user has been added, click on OKbutton:
17.用户已添加,点击OK按钮:


And it is finished the keyset does existnow!!
它完成了键组现在确实存在!!
回答by Mough
I ran into this error when I wasn't loading in the PrivateKey from my certificate into my signedXmlElement's SigningKey when trying to sign a SAML response.
我在尝试签署 SAML 响应时没有将 PrivateKey 从我的证书加载到我的 signedXmlElement 的 SigningKey 中时遇到了这个错误。
signedElement.SigningKey = myCertificate.PrivateKey;
回答by bryan.hunwardsen
I received same error as OP: "System.Security.Cryptography.CryptographicException: keyset does not exist"
我收到与 OP 相同的错误:“System.Security.Cryptography.CryptographicException:keyset does not exist”
The resolution (for me) was: Visual Studio needs to be (run as Admin)
解决方案(对我而言)是:Visual Studio 需要(以管理员身份运行)
As was explained to me(YMMV), VS needs to be run as Admin in order to extract the certificates private key from the key store, in order to negotiate auth/handshake with keyvault.
正如向我解释的那样(YMMV),VS 需要以管理员身份运行才能从密钥库中提取证书私钥,以便与密钥库协商身份验证/握手。
回答by Johnny Graber
I did run into the same problem. The message is not ideal and in my case my user did not have permission to access the private key. You can fix this using these steps:
我确实遇到了同样的问题。该消息并不理想,在我的情况下,我的用户无权访问私钥。您可以使用以下步骤解决此问题:
- Open mmc
- Add certificate snap-in
- select the certificate you want to use
- right click on it and select 'All Tasks' / 'Manage Private Keys...'
- Add your user to the list of authorized users and allow 'Full Control'
- 打开 mmc
- 添加证书管理单元
- 选择您要使用的证书
- 右键单击它并选择“所有任务”/“管理私钥...”
- 将您的用户添加到授权用户列表并允许“完全控制”
回答by Bhavesh
Try running vs as Administrator. Worked for me
尝试以管理员身份运行 vs。为我工作
回答by Dai Bok
In my case the private key was stored in "C:\ProgramData\Microsoft\Crypto\Keys"and not machinekeys folder - you can check using certutil to find out the "Unique container name" that will be the private key.
在我的情况下,私钥存储在"C:\ProgramData\Microsoft\Crypto\Keys"而不是 machinekeys 文件夹中 - 您可以使用 certutil 检查以找出将成为私钥的“唯一容器名称”。
I now scan through the crypto directory to find the match. WIth that match I can set the correct ACL on the appropriate file
我现在扫描加密目录以找到匹配项。通过匹配,我可以在适当的文件上设置正确的 ACL

