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_等)位于此处。