代码之家  ›  专栏  ›  技术社区  ›  Kiquenet user385990

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

  •  4
  • Kiquenet user385990  · 技术社区  · 14 年前

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

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

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

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

    证书是PFX文件。请安装PFX并使用向导。密钥私有不检查导出。 输入密码并安装。

    有一个应用程序Web,AppPool标识为:网络服务帐户。

    web服务器是IIS 6.0。

    在2001年以前,

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

    发给ENTIDAD公司的保险单SA-CIF A93-名称1

    由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姓氏1名称1”-g-a“网络服务”

    结果是:

    匹配证书:

    CN=ENTIDAD公司投保SA-CIF A93-姓名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姓1名1”

    结果是:

    匹配证书:

    OU=700012476

    O=FNMT

    C=ES

    其他帐户和组 对私钥的访问包括: 权限/系统 内置\Administrators NT

    现在,在服务器Win2003、IIS 6.0的应用程序web中的aspx页面中,我有以下代码:

    注意:X509Certificate2.HasPrivateKeyAccess()的值对于“ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE姓1名1”证书为否(错误)。

    使用identity::NT AUTHORITY\NETWORK服务执行ASP.NET应用程序

    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.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) 签字人) nombreCertificado,X509Certificate2认证 证书)中 c: \Company\App\Test\TestCert.aspx:行 242个

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

    bc a4广告58 c9 3c af 8b eb 0b 2f 86 c7

    FindPrivateKey公司 我的本地机器-n“ENTIDAD COMPANY INSURE SA-CIF A93-NOMBRE姓氏1名称1”a

    FindPrivateKey我的本地计算机-n 一

    FindPrivateKey帮助用户找到 的私钥文件的位置

    用法:FindPrivateKey[{{-n}{-t}

    主题名称 证明书

    的指纹 证书(使用certmgr.exe获取 信息技术)

    -f仅输出文件名

    -仅d输出目录

    -输出绝对文件 名称,如FindPrivateKey My 当前用户-n“CN=John Doe”

    “03 33 98 63 d0 47 e7 48 71 33 62 64 76 5摄氏度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

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

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

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

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

    有什么建议吗??

    3 回复  |  直到 14 年前
        1
  •  2
  •   Benjamin Cintix    14 年前

    请检查这个 document

    winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 
    
        2
  •  5
  •   Community CDub    8 年前

    前两步的步骤和你做的一样 IIS 7.5 (click here)

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

      • 用证书的主题替换[主题],如果包含空格,则使用引号。我想你也可以把第一个词放在第一个词上,只要没有另一个以同一主题开头的证书。
      • 将[存储]替换为您导入到的证书存储,默认情况下,我认为是IIS 6上的“根”或“我的”,即“本地计算机根”或“本地计算机我的”
      • 用计算机名替换[计算机名]。您可能可以为[computernam]使用“.\”符号,即“.\NETWORK SERVICE”,但我还没有尝试过。

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

    注: 如果在“网络服务”以外的标识下运行ASP.NET应用程序池,则需要将上述命令中的“网络服务”更改为运行IIS应用程序池的标识。

        3
  •  0
  •   Mike    14 年前

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