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

The template parameter in InitializeFromPrivateKey() on CX509CertificateRequestPkcs10 object causes exception when trying a specific Template

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

certenroll::cx509certificaterequestpkcs10::initializeFromPrivateKey:此CA不支持请求的证书模板。0x80094800(-2146875392)

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

javascript代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 <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);
    }

其他几个问题-我假设模板应该存在于客户机上?否则,它如何知道查询模板的CA的位置?-客户机上的certenroll是否在Windows 2003 CA服务器上工作??

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

附加信息-客户端是Windows7,MS IE9客户端以管理员身份运行。-承载上述页面的Web应用程序通过HTTPS访问。-Web应用程序托管在Win2003 CA服务器上。

在发帖之前,我看过…-有关certenroll+initializefromprivatekey的stackoverflow线程-关于使用模板OID而非模板名称的博客-msdn/alejacma的网站-msdn上的certenroll api


好吧,我想……很典型。

  • 使用cx509extensionTemplateName,并使用OID模板值调用initializeEncode
  • 不要在InitializeFromPrivateKey中指定模板参数。

即:

1
2
3
4
5
6
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上验证了请求是针对指定的模板类型I的,并且确实只为该类型创建证书。

希望有一天这能帮助别人。


另请参阅此代码,其中我使用的是一个新的dll,它不包含您正在使用的方法。我也没有使用在部署或构建代码时导致问题的"互操作类型"。

1
2
3
4
5
6
7
8
 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);

在ServerFault上使用此方法可以获取OID

此代码的其他实现(vbs、c_等)位于此处。