证书:找不到用于解密的证书和私钥签名时出错

Kiq*_*net 4 account iis-6 windows-server-2003 x509certificate

我在公司工作,为开发人员提供许多服务器和PC。服务器是win2003,PC开发人员是Windows XP。

在预生产环境中的名为Winiis01的服务器Win2003中,公司中的其他人使用任何其他用户(domainCompany \ adminsystems)安装客户端证书,以登录服务器preiis01。

任何管理员都使用用户“ domainCompany \ adminsystems”登录服务器preiis01(使用Windows XP的远程服务器终端服务器)。

管理员用户是domainCompany \ adminsystems“,它将安装证书。

管理员用户按以下方式安装它:

会话登录(例如“ domainCompany \ adminsystems”)证书是PFX文件。请安装PFX并使用向导。密钥私有不检查导出。输入密码并安装。

有一个应用程序Web,其AppPool身份为:网络服务帐户。

Web服务器是IIS 6.0。

在preiis01中,

该管理员用户执行mmc->管理单元->本地计算机证书。在节点->个人->证书中,他看到了客户端证书:

颁发给ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE SURNAME1 NAME1

由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“网络服务”

结果是:

配套证书:

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 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(否)。

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;
 }

}
Run Code Online (Sandbox Code Playgroud)

该代码对我而言失败,并且出现以下错误:找不到用于解密的证书和私钥。

错误行是:signedCms.ComputeSignature(cmsSigner);

确认证书错误:System.Security.Cryptography.CryptographicException:找不到用于解密的证书和私钥。

在System.Security.Cryptography.Pkcs.PkcsUtils.CreateSignerEncodeInfo(CmsSigner签名者,布尔无声)处,在System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature处(CmsSigner签署者,布尔值无声)位于c:\ Company \ App \ Test \ ASP.dgsfp_test_testcert_aspx.FirmarConCertificado(String nombreCertificado,X509CertCate2证书)中System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner签署者) 242行

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

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

FindPrivateKey我的本地计算机-n“ ENTIDAD公司保险SA-CIF A93-NOMBRE SURNAME1 NAME1” –a

FindPrivateKey我的本地计算机-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组中的管理员,具有本地策略:“作为服务登录”

我在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:找不到用于解密的证书和私钥

有什么建议么 ??

tha*_*mes 5

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

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

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

winhttpcertcfg.exe -g -a“ [计算机名称] \ NETWORK SERVICE” -c LOCAL_MACHINE \ [存储] -s“ [主题]”

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