CX509CertificateRequestPkcs10 对象的 InitializeFromPrivateKey() 中的模板参数在尝试特定模板时导致异常

Posted

技术标签:

【中文标题】CX509CertificateRequestPkcs10 对象的 InitializeFromPrivateKey() 中的模板参数在尝试特定模板时导致异常【英文标题】:The template parameter in InitializeFromPrivateKey() on CX509CertificateRequestPkcs10 object causes exception when trying a specific Template 【发布时间】:2011-10-21 00:12:41 【问题描述】:

我在 X509Enrollment.CX509CertificateRequestPkcs10 对象的 InitializeFromPrivateKey() 中指定模板参数时遇到问题。除了 "User" 的模板之外的任何内容都会导致以下异常:-

CertEnroll::CX509CertificateRequestPkcs10::InitializeFromPrivateKey:此 CA 不支持请求的证书模板。 0x80094800 (-2146875392)

我需要使用一个特定的证书模板,当我尝试它时,代码会抛出异常。模板存在于 CA 和运行以下代码的客户端机器上。

javascript代码如下:

 <script type="text/javascript">

     var sCertificate = null;
     var sDistinguishedName = "C=\"\";S=\"\";L=\"\";O=\"XXXXX\";OU=\"XXXXXXX\";E=\"XXXXX@XXXX.com\";CN=\"xxxxxxx\";";
     var template = "RegistrationCert"; //Anything Other than "User" fails, have tried template Oid too.

     var classFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");
     var objEnroll = classFactory.CreateObject("X509Enrollment.CX509Enrollment");
     var objPrivateKey = classFactory.CreateObject("X509Enrollment.CX509PrivateKey");
     var objRequest = classFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");
     var objDN = classFactory.CreateObject("X509Enrollment.CX500DistinguishedName");

     objPrivateKey.ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0";
     objPrivateKey.KeySpec = "1";
     objPrivateKey.ProviderType = "1";

    try 
    
            objRequest.InitializeFromPrivateKey(1, objPrivateKey, template);
            objDN.Encode(sDistinguishedName, 0);
            objRequest.Subject = objDN;
            objEnroll.InitializeFromRequest(objRequest);
            sCertificate = objEnroll.CreateRequest(1);
            document.writeln(sCertificate);
    
    catch (ex)
    
             document.writeln(ex.description);
    
 </script>

其他几个问题 - 我假设模板应该存在于客户端机器上?否则它怎么知道 CA 的位置来查询模板? - 客户端上的 CertEnroll 甚至可以针对 Windows 2003 CA 服务器工作吗??

如果您能帮助我,将不胜感激!!!

其他信息 - 客户端是 Windows 7,以管理员身份运行 MS IE9 客户端。 - 通过 HTTPs 访问托管上述页面的 Web 应用程序。 - Web 应用程序托管在 Win2003 CA 服务器上。

在发帖之前,我查看了... - 关于 CertEnroll + InitializeFromPrivateKey 的 *** 线程 - Blogs about using Template OID not Template name - MSDN / alejacma's Site - MSDN 上的 CertEnroll API

【问题讨论】:

【参考方案1】:

好吧,这么想吧..典型的。

使用 CX509ExtensionTemplateName,并使用 OID 模板值调用 InitializeEncode 不要在 InitializeFromPrivateKey 中指定模板参数。

即:

var objExtensionTemplate = classFactory.CreateObject("X509Enrollment.CX509ExtensionTemplateName")


objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); //empty string, don't specify template here
objExtensionTemplate.InitializeEncode(template); //Specify Template as OID value!
objRequest.X509Extensions.Add(objExtensionTemplate);

已在 CA 上验证该请求是针对我指定的模板类型的,并且确实只为该类型创建了一个证书。

希望有一天这对某人有所帮助。

【讨论】:

+1 回来告诉我们您已修复它以及您是如何做到的。你用的太对了!【参考方案2】:

另请参阅此代码,我在其中使用了不包含您正在使用的方法的较新 DLL。我也没有使用"interop types",这会在部署或构建代码时出现问题。

 CObjectId EkuOid = new CObjectId();
        EkuOid.InitializeFromValue("1.3.6.1.4.1.311.21.8.4946465.16405226.12930948.10533807.2139545.33.5005369.11644649");
        CObjectIds EkuOids = new CObjectIds();
        EkuOids.Add(EkuOid);
        CX509ExtensionEnhancedKeyUsage eku = new CX509ExtensionEnhancedKeyUsage();
        eku.InitializeEncode(EkuOids);
        eku.Critical = false;
        objPkcs10.X509Extensions.Add((CX509Extension)eku);

可以使用this method on serverfault获取OID

此代码的替代实现(VBS、C# 等)is located here.

【讨论】:

以上是关于CX509CertificateRequestPkcs10 对象的 InitializeFromPrivateKey() 中的模板参数在尝试特定模板时导致异常的主要内容,如果未能解决你的问题,请参考以下文章

IE9,使用 CertEnroll.dll 时自动化服务器无法创建对象错误

Azure 上的 Certenroll - 生成自签名证书

客户端证书 Web 服务调用

x509的简介

Bouncycastle:X509CertificateHolder 到 X509Certificate?

X509Chain.Build(...) System.InvalidCastException 从 X509Certificate 到 X509Certificate2