证书:找不到用于解密的证书和私钥签名时出错
我在为开发人员提供许多服务器和个人电脑的公司工作。服务器是win2003,开发PC是Windows XP。
在名为 preiis01 的服务器 Win2003 中,在预生产环境中,公司其他人员使用任何其他用户(domainCompany\adminsystems)安装客户端证书,用于登录服务器 preiis01。
任何管理员都使用用户“domainCompany\adminsystems”登录服务器 preiis01(使用终端服务器、Windows XP 的远程桌面)。
管理员用户是domainCompany\adminsystems”,它安装证书。
管理员用户如下安装:
会话登录如“domainCompany\adminsystems” 证书是PFX文件。安装 PFX 并使用向导。密钥私有不检查导出。 输入密码并安装。
有一个应用程序Web,其AppPool Identity是:NETWORK SERVICE帐户。
Web服务器是IIS 6.0。
在 preiis01 中,
管理员用户执行 mmc ->咬入 ->本地计算机的证书。在节点->个人->证书,他看到了客户端证书:
Issued To ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
Issued By FNMT Clase 2 CA
在证书的属性中,指纹:“93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13"
该管理员用户执行以下命令:
winhttpcertcfg.exe LOCAL_MACHINE\My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" -g -a "NETWORK SERVICE"
结果是:
匹配证书:
CN=ENTIDAD 公司保险 SA - CIF A93 - 姓名 1 姓名 1
OU=703015476
OU=FNMT 2 类 CA
O=FNMT
C=ES
授予私钥访问权限 帐户:NT AUTHORITY\NETWORK SERVICE
现在,管理员用户执行以下命令:
winhttpcertcfg.exe -l -c LOCAL_MACHINE\My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1"
结果是:
匹配证书:
CN=ENTIDAD 公司保险 SA - CIF A93 - 姓名 1 姓名 1
OU=700012476
OU=FNMT 2 类 CA
O=FNMT
C=ES
其他帐户和组 私钥的访问包括: 域公司\adminsystems NT 权威\制度 内置\管理员 NT 权威机构\网络服务
现在,在服务器 Win2003、IIS 6.0 中的应用程序 Web 的 aspx 页面中,我有以下代码:
注意:对于“ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE,X509Certificate2.HasPrivateKeyAccess() 的值是 NO(假)”姓1名1”证书。
ASP.NET 应用程序使用身份执行:: NT AUTHORITY\NETWORK SERVICE
lbInfo.Text += "<br/><br/>ASP.NET application executes using the identity :: <b>" + WindowsIdentity.GetCurrent().Name + "</b><br>";
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
Certificates = store.Certificates;
repeater1.DataSource = Certificates;
repeater1.DataBind();
var nombreCertificado = "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1";
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySubjectName, nombreCertificado, false);
if (col.Count > 0)
{
X509Certificate2 certificate = col[0];
store.Close();
Message.Text = "Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
FirmarConCertificado(nombreCertificado, certificate);
}
else
{
store.Close();
Message.Text = "El certificado " + nombreCertificado + " no esta instalado en la máquina";
}
public void FirmarConCertificado(string nombreCertificado, X509Certificate2 certificate)
{
try
{
var mensaje = "Datos de prueba";
System.Text.Encoding enc = System.Text.Encoding.Default;
byte[] data = enc.GetBytes(mensaje);
var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(data);
var signedCms = new System.Security.Cryptography.Pkcs.SignedCms(contentInfo, true);
var cmsSigner = new System.Security.Cryptography.Pkcs.CmsSigner(certificate);
// Sign the CMS/PKCS #7 message
signedCms.ComputeSignature(cmsSigner);
// Encode the CMS/PKCS #7 message
var ret = Convert.ToBase64String(signedCms.Encode());
Message.Text += "Firmado con Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
}
catch (Exception ex)
{
Message.Text = "Error al firmar con certificado: " + ex.ToString();
Message.Text += "<br /><br />InnerException: " + ex.InnerException;
}
}
该代码对我来说失败,并且出现此错误:找不到用于解密的证书和私钥。
错误行是:signedCms.ComputeSignature(cmsSigner);
固定证书错误: System.Security.Cryptography.CryptographicException: 找不到证书并且 用于解密的私钥。
在 System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner 签名者,布尔值无声)在 System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner 签名者,布尔值无声)在 System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner 签名者,布尔值无声)在 System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner 签名者)于 ASP.dgsfp_test_testcert_aspx.FirmarConCertificado(字符串 名称证书,X509Certificate2 证书)在 c:\Company\App\Test\TestCert.aspx:line 242
然后,管理员用户(我记得是安装证书的人)执行以下命令:
FindPrivateKey 我的本地机器 -t "93 BC A4 AD 58 C9 3C AF 8B EB 0B 2F 86 C7 9d 81 70 a6 c4 13" –c
查找私钥 我的 LocalMachine -n "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" –a
FindPrivateKey 我的本地机器 -n “CN=ENTIDAD 公司保险 SA - CIF A93 - 姓名 1 姓名 1” –a
所有 3 个命令的结果相同:
FindPrivateKey帮助用户找到 私钥文件的位置 X.50 9 证书。
用法:FindPrivateKey [{ {-n } | {-t} } [-f | -d | -a]]
主题名称 证书
的指纹 证书(使用 certmgr.exe 获取 它)
-f 仅输出文件名
-d 仅输出目录
-输出绝对文件 名称 例如 FindPrivateKey My 当前用户 -n "CN=John Doe"
例如 FindPrivateKey 我的本地机器 -t “03 33 98 63 d0 47 e7 48 71 33 62 64 76 5 c 4c 9d 42 1d 6b 52" -c
FindPrivateKey 没有得到任何东西,但 winhttpcertcfg.exe -l 工作正常(匹配证书)
我们已使用 winhttpcertcfg.exe 工具和代码向网络服务用户授予权限ASP.NET(在网络服务帐户下执行)找到证书,但使用证书签名时失败。
如果有人可以向我们提供一些信息或建议
更新:
域“domainCompany\Pre_Certificado”中的用户在存储本地计算机中安装证书。
domainCompany\Pre_Certificado 是管理员,位于 IIS_WPG 组中,具有本地策略:“作为服务登录”
我在 IIS 6.0 中为以下内容配置 AppPool 标识:domainCompany\Pre_Certificado
ASP.NET 应用程序使用身份执行::domainCompany\Pre_Certificado
我回收 AppPool 并执行应用程序中,我得到 System.Security.Cryptography.CryptographicException:无法找到用于解密的证书和私钥
如果我再次测试,使用domainCompany\Pre_Certificado 用户登录服务器 IIS 中的会话,我在 ASP.NET 应用程序中调用页面,一切都是好的。
(注意:使用终端服务器登录服务器 IIS)
但是如果在服务器 IIS 中注销会话(用户:domainCompany\Pre_Certificado),我会得到相同的错误:
System.Security.Cryptography.CryptographicException:无法找到用于解密的证书和私钥
有什么建议吗?
I work in company with many servers and Pcs for developers. Servers are win2003, PC developers Windows XP.
In a server Win2003 named preiis01, in preproduction environment, other people in company install a client certificate using any other user (domainCompany\adminsystems) for logging in server preiis01.
Anyone admin uses the user "domainCompany\adminsystems" for log in server preiis01 (using Terminal Server, Remote Desktop for Windows XP).
the admin user is domainCompany\adminsystems", which installs certificate.
Admin user install it like this:
Session login like "domainCompany\adminsystems"
Certificate is PFX file. Do Install PFX and using Wizard. The key private not check for export.
Input the password and install.
There is an application Web which AppPool Identity is: NETWORK SERVICE account.
web server is IIS 6.0.
in preiis01,
That admin user executes mmc -> Snap in -> Certificates for Local Machine. In node -> Personal -> Certificates, he had seen the client certificate:
Issued To ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
Issued By FNMT Clase 2 CA
In properties of certificate, the thumbprint: "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13"
That admin user executes this commands:
winhttpcertcfg.exe LOCAL_MACHINE\My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" -g -a "NETWORK SERVICE"
Result is:
Matching certificate:
CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
OU=703015476
OU=FNMT Clase 2 CA
O=FNMT
C=ES
Granting private key access for
account: NT AUTHORITY\NETWORK SERVICE
Now, admin user executes this command:
winhttpcertcfg.exe -l -c LOCAL_MACHINE\My -s "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1"
The result is:
Matching certificate:
CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
OU=700012476
OU=FNMT Clase 2 CA
O=FNMT
C=ES
Additional accounts and groups with
access to the private key include:
domainCompany\adminsystems NT
AUTHORITY\SYSTEM
BUILTIN\Administrators NT
AUTHORITY\NETWORK SERVICE
NOw, in an aspx page in application web in server Win2003, IIS 6.0, I have this code:
NOte: value for X509Certificate2.HasPrivateKeyAccess() is NO (false) for "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" certificate.
ASP.NET application executes using the identity :: NT AUTHORITY\NETWORK SERVICE
lbInfo.Text += "<br/><br/>ASP.NET application executes using the identity :: <b>" + WindowsIdentity.GetCurrent().Name + "</b><br>";
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
Certificates = store.Certificates;
repeater1.DataSource = Certificates;
repeater1.DataBind();
var nombreCertificado = "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1";
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySubjectName, nombreCertificado, false);
if (col.Count > 0)
{
X509Certificate2 certificate = col[0];
store.Close();
Message.Text = "Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
FirmarConCertificado(nombreCertificado, certificate);
}
else
{
store.Close();
Message.Text = "El certificado " + nombreCertificado + " no esta instalado en la máquina";
}
public void FirmarConCertificado(string nombreCertificado, X509Certificate2 certificate)
{
try
{
var mensaje = "Datos de prueba";
System.Text.Encoding enc = System.Text.Encoding.Default;
byte[] data = enc.GetBytes(mensaje);
var contentInfo = new System.Security.Cryptography.Pkcs.ContentInfo(data);
var signedCms = new System.Security.Cryptography.Pkcs.SignedCms(contentInfo, true);
var cmsSigner = new System.Security.Cryptography.Pkcs.CmsSigner(certificate);
// Sign the CMS/PKCS #7 message
signedCms.ComputeSignature(cmsSigner);
// Encode the CMS/PKCS #7 message
var ret = Convert.ToBase64String(signedCms.Encode());
Message.Text += "Firmado con Certificado " + nombreCertificado + " encontrado en " + StoreLocation.LocalMachine;
}
catch (Exception ex)
{
Message.Text = "Error al firmar con certificado: " + ex.ToString();
Message.Text += "<br /><br />InnerException: " + ex.InnerException;
}
}
The code fails for me, and I get this error: Cannot find the certificate and private key for decryption.
Error line is:signedCms.ComputeSignature(cmsSigner);
Error al firmar con certificado:
System.Security.Cryptography.CryptographicException:
Cannot find the certificate and
private key for decryption.at
System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner
signer, Boolean silent) at
System.Security.Cryptography.Pkcs.SignedCms.Sign(CmsSigner
signer, Boolean silent) at
System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner
signer, Boolean silent) at
System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner
signer) at
ASP.dgsfp_test_testcert_aspx.FirmarConCertificado(String
nombreCertificado, X509Certificate2
certificate) in
c:\Company\App\Test\TestCert.aspx:line
242
Then, the admin user (I remember, who install the certificate) executes this commands:
FindPrivateKey My LocalMachine -t "93
bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7
9d 81 70 a6 c4 13" –cFindPrivateKey
My LocalMachine -n "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" –aFindPrivateKey My LocalMachine -n
"CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1"
–a
The result for all 3 commands is the same:
FindPrivateKey helps user to find the
location of the Private Key file of a
X.50 9 Certificate.Usage: FindPrivateKey [{ {-n } | {-t }
} [-f | -d | -a]]subject name of the
certificatethumbprint of the
certificate (use certmgr.exe to get
it)-f output file name only
-d output directory only
-a output absolute file
name e.g. FindPrivateKey My
CurrentUser -n "CN=John Doe"e.g. FindPrivateKey My LocalMachine -t
"03 33 98 63 d0 47 e7 48 71 33 62 64
76 5 c 4c 9d 42 1d 6b 52" -c
FindPrivateKey don't get anything, but winhttpcertcfg.exe -l works fine (matching certificate)
We have given privileges to the Network Service user using the winhttpcertcfg.exe tool, and in code ASP.NET (execute under Network Service account) the certificate is found. But fails when sign using certificate.
If someone could give us some information about, or suggestions
update:
User in domain "domainCompany\Pre_Certificado" install Certificate in Store Local Machine.
domainCompany\Pre_Certificado is Administrator, in IIS_WPG group, has Local Policies: “Log on as Service“
I configure AppPool Identity in IIS 6.0 for : domainCompany\Pre_Certificado
ASP.NET application executes using the identity :: domainCompany\Pre_Certificado
I recycle AppPool and execute application, I get System.Security.Cryptography.CryptographicException: Cannot find the certificate and private key for decryption
If I test again, log in session in server IIS, using domainCompany\Pre_Certificado user, I call page in ASP.NET application and all is OK.
(note: log in server IIS using Terminal Server)
But if log off session in server IIS (user: domainCompany\Pre_Certificado), I get the same error:
System.Security.Cryptography.CryptographicException: Cannot find the certificate and private key for decryption
Any suggestions ??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
按照与 IIS 7.5(单击此处)
以管理员身份运行以下命令。替换以下内容:
winhttpcertcfg.exe -g -a "[computername]\NETWORK SERVICE" -c LOCAL_MACHINE\[Store] -s "[Subject]"
注意: 如果您正在某个身份下运行 ASP.NET 应用程序池除了“NETWORK SERVICE”之外,您还需要将上述命令中的“NETWORK SERVICE”更改为您正在运行 IIS 应用程序池的标识。
Do the first 2 steps as the same as you would with IIS 7.5 (click here)
Run the below command as an administrator. Replace the following:
winhttpcertcfg.exe -g -a "[computername]\NETWORK SERVICE" -c LOCAL_MACHINE\[Store] -s "[Subject]"
Note: If you are running ASP.NET Application Pool under an identity other than "NETWORK SERVICE" you'll need the change "NETWORK SERVICE" in the above command to the identity that you're running the IIS application pool.
请查看此文档,它将帮助您解决问题。我建议使用以下命令选项:
Please check this document which would help you to resolve the issue. I would recommend to use following command option:
可能还需要向匿名用户授予访问权限。如果您允许匿名访问,则请求将以匿名用户而不是网络服务的身份运行。
May need to grant access to the anonymous user also. If you are allowing anonymous access then the request is running as the anonymous user not network service.