【发布时间】:2011-04-25 13:32:19
【问题描述】:
我与许多服务器和个人电脑一起工作,供开发人员使用。服务器是win2003,PC开发者Windows XP。
在名为preiis01的Win2003服务器中,在预生产环境中,公司中的其他人使用任何其他用户(domainCompany\adminsystems)安装客户端证书以登录服务器preiis01。
任何管理员都使用用户“domainCompany\adminsystems”登录服务器 preiis01(使用终端服务器,Windows XP 的远程桌面)。
admin 用户是 domainCompany\adminsystems",用于安装证书。
管理员用户像这样安装它:
像“domainCompany\adminsystems”这样的会话登录 证书是 PFX 文件。安装 PFX 并使用向导。密钥私有不检查导出。 输入密码并安装。
有一个应用Web,其AppPool Identity是:NETWORK SERVICE account。
网络服务器是 IIS 6.0。
在preiis01中,
该管理员用户执行 mmc -> 管理单元 -> 本地计算机的证书。在节点 -> 个人 -> 证书中,他看到了客户端证书:
发给 ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
由 FNMT 第 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 COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
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 COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1
OU=700012476
OU=FNMT 2 类 CA
O=FNMT
C=ES
其他帐户和组 对私钥的访问包括: domainCompany\adminsystems NT 权限\系统 内置\管理员 NT 授权\网络服务
现在,在服务器 Win2003、IIS 6.0 的应用程序 web 的 aspx 页面中,我有以下代码:
注意:对于“ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1”证书,X509Certificate2.HasPrivateKeyAccess() 的值为 NO (false)。
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);
错误 alfirmar con certificado: 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(字符串 别名Certificado, X509Certificate2 证书)在 c:\Company\App\Test\TestCert.aspx:line 242
然后,管理员用户(我记得是安装证书的)执行以下命令:
FindPrivateKey 我的 LocalMachine -t "93 公元前 a4 广告 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13" -c
查找私钥 My LocalMachine -n "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" –a
FindPrivateKey 我的 LocalMachine -n “CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1” --a
所有 3 个命令的结果都是一样的:
FindPrivateKey 帮助用户找到 私钥文件的位置 X.50 9 证书。
用法:FindPrivateKey [{ {-n } | {-t} } [-f | -d | -a]]
的主题名称 证书
的指纹 证书(使用 certmgr.exe 获取 它)
-f 只输出文件名
-d 仅输出目录
-输出绝对文件 名称例如FindPrivateKey 我的 CurrentUser -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 中为:domainCompany\Pre_Certificado 配置 AppPool Identity
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:找不到用于解密的证书和私钥
有什么建议吗??
【问题讨论】:
标签: iis-6 windows-server-2003 x509certificate account