4

我与许多服务器和开发人员的 PC 一起工作。服务器是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 -> Snap in -> 本地计算机证书。在节点 -> 个人 -> 证书中,他看到了客户端证书:

签发给 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 "网络服务"

结果是:

配套证书:

CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1

欧=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 AUTHORITY\SYSTEM BUILTIN\Administrators NT AUTHORITY\NETWORK SERVICE

现在,在服务器 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);

Error 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(字符串 nombreCertificado,X509Certificate2 证书)在 c:\Company\App\Test\TestCert.aspx:第 242 行

然后,管理员用户(我记得是安装证书的)执行以下命令:

FindPrivateKey My LocalMachine -t "93 bc a4 ad 58 c9 3c af 8b eb 0b 2f 86 c7 9d 81 70 a6 c4 13" –c

FindPrivateKey My LocalMachine -n​​ "ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" –a

FindPrivateKey My LocalMachine -n​​ "CN=ENTIDAD COMPANY INSURE SA - CIF A93 - NOMBRE SURNAME1 NAME1" –a

所有 3 个命令的结果都是相同的:

FindPrivateKey 帮助用户找到 X.50 9 证书的私钥文件的位置。

用法:FindPrivateKey [{ {-n } | {-t } } [-f | -d | -一个]]

证书的主题名称

证书的指纹(使用 certmgr.exe 获取)

-f 只输出文件名

-d 仅输出目录

-a 输出绝对文件名,例如 FindPrivateKey My CurrentUser -n "CN=John Doe"

例如 FindPrivateKey 我的 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 没有得到任何东西,但 winhttpcertcfg.exe -l 工作正常(匹配证书)

我们使用 winhttpcertcfg.exe 工具为网络服务用户授予了权限,并且在代码 ASP.NET(在网络服务帐户下执行)中找到了证书。但是使用证书签名时失败。

如果有人可以给我们一些信息或建议

更新:

域“domainCompany\Pre_Certificado”中的用户在存储本地计算机中安装证书。

domainCompany\Pre_Certificado 是管理员,在 IIS_WPG 组中,具有本地策略:“作为服务登录”</p>

我在 IIS 6.0 中配置 AppPool Identity 为:domainCompany\Pre_Certificado

ASP.NET 应用程序使用身份执行:: domainCompany\Pre_Certificado

我回收 AppPool 并执行应用程序,我得到 System.Security.Cryptography.CryptographicException: 找不到用于解密的证书和私钥

如果我再次测试,在服务器 IIS 中登录会话,使用 domainCompany\Pre_Certificado 用户,我在 ASP.NET 应用程序中调用页面,一切正常。

(注意:使用终端服务器登录服务器 IIS)

但是如果在服务器 IIS 中注销会话(用户:domainCompany\Pre_Certificado),我会得到同样的错误:

System.Security.Cryptography.CryptographicException:找不到用于解密的证书和私钥

有什么建议么 ??

4

3 回答 3

5

执行与IIS 7.5相同的前 2 个步骤(单击此处)

  1. 创建/购买证书。确保它有一个私钥。
  2. 将证书导入“本地计算机”帐户。最好使用证书 MMC。确保选中“允许导出私钥”
  3. 以管理员身份运行以下命令。替换以下内容:

    • 将 [Subject] 替换为证书的主题,如果包含空格,请使用引号。我认为只要没有以相同主题开头的其他证书,您也可以只输入第一个单词。
    • 将 [Store] 替换为您导入到的证书存储,我认为在 IIS 6 上默认为“ROOT”或“MY”,即“LOCAL_MACHINE\ROOT”或“LOCAL_MACHINE\MY”
    • 将 [computername] 替换为计算机的名称。您也许可以对 [computernam] 使用“.\”表示法,即“.\NETWORK SERVICE”,但我没有尝试过。

winhttpcertcfg.exe -g -a "[计算机名]\NETWORK SERVICE" -c LOCAL_MACHINE\[Store] -s "[主题]"

注意:如果您以“NETWORK SERVICE”以外的身份运行 ASP.NET 应用程序池,则需要将上述命令中的“NETWORK SERVICE”更改为您正在运行 IIS 应用程序池的身份。

于 2010-11-17T20:09:23.050 回答
2

请查看此文档,该文档将帮助您解决问题。我建议使用以下命令选项:

winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 
于 2010-11-17T15:33:25.123 回答
0

可能还需要授予匿名用户访问权限。如果您允许匿名访问,则请求将作为匿名用户而不是网络服务运行。

于 2010-10-14T18:02:22.543 回答