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

发布于 2024-09-27 15:44:42 字数 6625 浏览 0 评论 0原文

我在为开发人员提供许多服务器和个人电脑的公司工作。服务器是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" –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

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
certificate

thumbprint 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

追星践月 2024-10-04 15:44:42

按照与 IIS 7.5(单击此处)

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

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

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)

  1. Create / Purchase certificate. Make sure it has a private key.
  2. Import the certificate into the "Local Computer" account. Best to use Certificates MMC. Make sure to check "Allow private key to be exported"
  3. Run the below command as an administrator. Replace the following:

    • Replace [Subject] with the certificate's subject and use quotes if it contains spaces. I think you can also just put the first word as long as there isn't another cert that starts with the same subject.
    • Replace [Store] with the certificate store you imported to, default I believe is "ROOT" or "MY" on IIS 6, i.e. "LOCAL_MACHINE\ROOT" or "LOCAL_MACHINE\MY"
    • Replace [computername] with the name of the computer. You might be able to use ".\" notation for [computernam] i.e. ".\NETWORK SERVICE" but I have not tried it.

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.

究竟谁懂我的在乎 2024-10-04 15:44:42

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

winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 

Please check this document which would help you to resolve the issue. I would recommend to use following command option:

winhttpcertcfg -g -c LOCAL_MACHINE\My -s MyCertificate -a TESTUSER 
且行且努力 2024-10-04 15:44:42

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文