How to create a certificate request with CertEnroll (JavaScript)

Hi all,

The following Javascript sample shows how to use CertEnroll COM component to create a certificate request:

<title>Certificate Request test</title>
<object id=”objCertEnrollClassFactory” classid=”clsid:884e2049-217d-11da-b2a4-000e7bbb2b09“></object>
<script language=”javascript”>

function CreateRequest()
document.write(“<br>Create Request…”);

try {
// Variables
var objCSP = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CCspInformation“);
var objCSPs = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CCspInformations“);
var objPrivateKey = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509PrivateKey“);
var objRequest = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509CertificateRequestPkcs10“)
var objObjectIds = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CObjectIds“);
var objObjectId = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CObjectId“);
var objX509ExtensionEnhancedKeyUsage = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509ExtensionEnhancedKeyUsage“);
var objExtensionTemplate = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509ExtensionTemplateName“)
var objDn = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX500DistinguishedName“)
var objEnroll = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509Enrollment“)

// Initialize the csp object using the desired Cryptograhic Service Provider (CSP)
objCSP.InitializeFromName(“Microsoft Enhanced Cryptographic Provider v1.0”);

// Add this CSP object to the CSP collection object

// Provide key container name, key length and key spec to the private key object
//objPrivateKey.ContainerName = “AlejaCMa”;
objPrivateKey.Length = 1024;
objPrivateKey.KeySpec = 1; // AT_KEYEXCHANGE = 1

// Provide the CSP collection object (in this case containing only 1 CSP object)
// to the private key object
objPrivateKey.CspInformations = objCSPs;

// Initialize P10 based on private key
objRequest.InitializeFromPrivateKey(1, objPrivateKey, “”); // context user = 1

// Oid – Extension

// Oid – Extension

// DN related stuff
objDn.Encode(“CN=alejacma”, 0); // XCN_CERT_NAME_STR_NONE = 0
objRequest.Subject = objDn;

// Enroll
var pkcs10 = objEnroll.CreateRequest(3); // XCN_CRYPT_STRING_BASE64REQUESTHEADER = 3

document.write(“<br>” + pkcs10);
document.write(“<br>The end!”);
catch (ex) {
document.write(“<br>” + ex.description);
return false;

return true;




And the following Javascript sample shows how to install the response from the CA (Certificate Authority):

<title>Certificate Request test</title>
<object id=”objCertEnrollClassFactory” classid=”clsid:884e2049-217d-11da-b2a4-000e7bbb2b09“></object>
<script language=”javascript”>

function InstallCert()
document.write(“<br>Installing certificate…”);

try {
// Variables
var objEnroll = objCertEnrollClassFactory.CreateObject(“X509Enrollment.CX509Enrollment“)

“h25CSWewZhpgbZkKPATLzidc0EjrWLl74RU32HEqkl2+R7yAdBQjMQA=” +

objEnroll.Initialize(1); // ContextUser
objEnroll.InstallResponse(0, sPKCS7, 6, “”); // AllowNone = 0, XCN_CRYPT_STRING_BASE64_ANY = 6
catch (ex) {
document.write(“<br>” + ex.description);
return false;

return true;




Note: this code must be run in the same machine where we made the request.

Note: these samples just create the request and install the response from the CA. If we need to send the request to the CA and get its response programmatically, the following C# sample may help with the objects and methods we can use to achieve this: How to create a certificate request with CertEnroll and .NET (C#).

I hope this helps.



Alex (Alejandro Campos Magencio)

Comments (54)

  1. Maxi says:


    great article, it was really helpful!

    I have a small doubt, though: I am creating a request using a Smart Card reader and I have noticed that after invoking CreateRequest() a request is inserted in the card. This was not the case with xenroll under Windows XP.

    Is this the expected behavior? Can I prevent CreateRequest() from inserting the request in the card?

    Thanks and keed posting!

  2. erwin says:

    Would you be able to help me create a asp script to generate a CSR for a IIS entry.  And another script to install the cert purchased from GeoTrust?  How much would you charge for something like this? Please email me at

  3. People open incidents/cases with MS Technical Support in their respective countries, and if the country is in my area and the question is related to the technologies that my team supports, I may take the case. Otherwise colleagues of mine will take it. I don’t support IIS related stuff, for instance. Another team does.

    Additionally, I can’t tell how much MS charges for these services. Also take into account the following limitations:

    1) This kind of "How to" questions are called Advisories, they are not support incidents, and only customers with a Premier contract with Microsoft can open them. They are charged by the hour.

    2) We won’t create custom code, we will only provide with samples/documentation to assist customers to create their own production code.

    If you have any question though, feel free to contact MS Technical Support.



  4. Rafael says:

    That code doesn’t work in html frames, I think. In my case appears the message "CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: Unspecified error 0x80004005 (-2147467259)" and Certenroll don’t load, If I don’t use frames it works great.

  5. Craig Martin says:

    This is a great little article. I appreciate the sample code as I am finding it very hard to find sample code for certenroll.

    One question: I have this all working, but when I go to install the certificate I have generated (I work for QuoVadis Limited who is a certificate authority so am using a dev CA to generate the certificate) I get the following error:

    "CertEnroll::CX509Enrollment::p_InstallResponse: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider 0x800b0109 (-2146762487)"

    I have the root and issuing CA certs installed on the PC and I even tried installing a PEM with chain version of the certificate that includes the root and issuing CA certificates, but I am still getting this error. Any idea why this is happening?

    Any help with this would be greatly appreciated!


    Craig Martin

    VP Software Development

    QuoVadis Limited

  6. I’m not sure without knowing the details of your environment or debugging the code itself, but this could be related:

    Error message when a user uses Internet Explorer 7 to open the certificate enrollment Web page to install an end entity certificate on a Windows Vista-based client computer;EN-US;945121

    If that doesn’t help, I suggest you open a case with us, Microsoft Technical Support. If you are in EMEA region, I may assist you personally.


  7. emre_erkan says:

    I copied this code to an aspx file and get

    Object doesn’t support this property or method

    in line

    var objCSP = objCertEnrollClassFactory.CreateObject("X509Enrollment.CCspInformation");

    with win 7

    any idea why ?  

  8. emre_erkan says:

    my mistake. it was IE security. Thanks for the nice article

  9. jay says:

    Hi, I get this error. what could this mean? i’ve tried IE security to enable all possible tweaks.


    Webpage error details

    User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)

    Timestamp: Tue, 22 Dec 2009 06:33:55 UTC

    Message: CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: The operation was canceled by the user. 0x800704c7 (WIN32: 1223)

    Line: 43

    Char: 9

    Code: 0

    URI: https://intranet/user/mycertrequestIE.php

  10. emre erkan says:

    Hi Craig,

    Your Answer is

               objEnroll.InstallResponse(0x00000004, cert, 6, ""); // AllowUntrustedRoot = 4

    If your root certificate is not trusted. You may use AllowUntrustedRoot instead of AllowNone (=0)

    Hi Jay, you should look at security restrictions about Activex. When you enable/prompt download unsigned activex controls it should work.

    I have another question; I can create request and install certificate. I see the certificate in my certificates. But when the user goes to the web site no certificate windows pops up. If I force popup via capicom, I do not see the installed certificate in the popup list. Any idea why?

  11. Emre, maybe it has to do with the available usages of that cert…

  12. emre erkan says:

    Hello again,

    With some support from MS, I learned that some changes to above code should be done.

    First of all key length should be 2048 and keyspec should remain default (unchanged)

    So if you update the certificate request like this it should work.

    objPrivateKey.Length = 1024;

    //objPrivateKey.KeySpec = 1; // AT_KEYEXCHANGE = 1

  13. Stephen says:


    I used info from this code as well as from various other sources to update our CA request code to work with Vista/IE7, and now I sat down at a new Win7/IE8 system to test it out (hoping it’d be fine with presumably the same CertEnroll stuff and major version number), but instead I get:

    Can’t create CSP List Object!  Error: -2147467259 :CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: Unspecified error 0x80004005 (-2147467259)

    and the crypto provider list, which is filtered down to "MS Enhanced Crypto Provider v1.0" on XP/Vista, is empty.

    Tried making sure the dev CA was trusted but still generates the same response.

    What’s different between Vista and Win7?  Or is it between IE7 and IE8?  Some browser security setting, or CLASSID change, or what?



  14. Stephen says:

    Actually, I guess I should have dug deeper, but just pulled the frame URLs out for requesting and installing a cert and went directly and Rafael’s right, it works without a hitch that way!  So what’s going on here?  Works in Vista with frames, only works in Win7 without frames.  Our CA uses frames and any requirement to change that is likely to be a pain.

    Any ideas?



  15. I really can’t tell why you are getting that error with frames. I would have to debug the issue, and for that I would need a support case to work with… You if you need help, I suggest you open a case with us.



  16. emre erkan says:

    Greetings all ,

    First of all its better to use objCertEnrollClassFactory before first use. In some cases (I don’t remember which cases ) I had error and using below declaration helped.

         var objCertEnrollClassFactory = document.applets(0);

    When using frames you may not access activex object directly and you may need to window.parent.document.applets(0);

    By the way if you have more than one activex/applet on your application you may need to use some other index than 0

  17. emre erkan says:

    I have a new problem; I can not install client certificate if there is a hierarchical chain for certificate server. Allow untrusted parameter which I mentioned above works only if you have standalone untrusted certificate server. Appreciate any help.

  18. Jay says:

    my comment above:

    Message: CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: The operation was canceled by the user. 0x800704c7 (WIN32: 1223)

    was responded by emre as:

    you should look at security restrictions about Activex. When you enable/prompt download unsigned activex controls it should work.

    To emre or anyone:

    how do we enabled download unsigned activex controls? I’ve already dealt with the options in IE, are there any other settings in Windows7. I’ve seen some computer policies in gpo, but that didnt work either.

    I’ve used to do this in vista, In vista I can see the pop-up to confirm if the user wants to used unsigned active X, but I’ve never seen this in Windows7.

    any help is highly appreciated

  19. Diego Cabrera says:


    i´m having troubles with frames, when execute the code in a single page it works, but into a frameset throws CreateObject: unexpected error 0x80004005 (-2147467259).

    Any idea how to solve this??


  20. Frank says:

    Hello together,

    I have same issue as Jay on Windows 7:

    Message: CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: The operation was canceled by the user. 0x800704c7 (WIN32: 1223)

    –> I tested it on Vista, too – there it works if you accept the activeX control prompt or add site to trusted.

    On Windows 7 it never works – reason seems to are higher restrictions for unsigned ActiveX controls. I also tried ActiveX Installation Service, where you can configure exceptions to general activeX handling rules – no effect.

    Has anyone successfully implemented and tested this for Windows 7?



  21. Frank says:


    for everyone who have the problem with frames and Windows 7 (in my case it was also the frame problem):

    It will work if CertEnroll Object is created in parent page and then accessed by framed page.

    Here some code to add it dynamically:

    Set both (parent and inner frame) via javascript to same document.domain value and then use parent.document.body.insertAdjacentHTML(‘afterBegin’,'<object id="objCertEnrollClassFactory_Proxy" classid="clsid:884e2049-217d-11da-b2a4-000e7bbb2b09" height=0 width=0></object> to insert the object to the parent frame. Than you can access it with objCertEnrollClassFactory = parent.objCertEnrollClassFactory_Proxy;



  22. Diego Cabrera says:

    Hi Frank,

    thanks for the answer, it works perfectly.

  23. miiiiichal says:

    Hello all,

    I got an error mentioned erlier by Rafael:

    "Error: CertEnroll::CX509EnrollmentWebClassFactory::CreateObject: Unspecified error. 0x80004005 (-2147467259)."

    I use construction like this:"

    function certEnroll(){

     this.classFactory= new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");

     this.objPrivKey = this.classFactory.CreateObject("X509Enrollment.CX509PrivateKey");


    Code works fine in IE7 & IE8 on Vista.

    Error occurs on Windows 7 (IE8) only when I run it in separate window opened from parent window.

    I get question If i want to run ActiveX. that mean the

    ActiveXObject is created but the CreateObejct method generates anexception.

    When I put url to my page direct into browser it works, but when I open new window by it doesn’t.

    I put my page to trusted pages and set security level in IE settings to low.

    Any ideas to solve this problem?



  24. Stephen says:

    Hi all–

    Just as an update, while I wasn’t able to plug in Frank’s suggestion as described, I was able to use it as the basis for something that does seem to have worked.  Still testing for verification purposes, but basically I ended up just moving the Object tag into the index.html file, then within the frames that would be using the object I ended up just adding the "parent." at the beginning of every reference.

    Somewhere I was having a problem trying to reassign the object from the parent level to something at the local level.  Probably just my own limited understanding of how to handle all that stuff (definitely not a VBS coder, or really much of a web page coder at all these days).

    Still checking on a potential minor issue or two with my resulting code, but looks like just moving the declaration/instantiation/whatever up to the parent document and calling it from there within the frames, was the critical piece.

    Thanks for the suggestion, Frank.


  25. Shaun says:

    I am testing something as basic as possible and coming up with this frame issue.  On the 2008R2 server, I have created a new file under CertSrv and called it certrqma2.asp

    Here are its contents:

    <html xmlns="; >


       <title>How easy it breaks</title>


    <frameset rows="100,*">

    <frame id="placeholder" name="placeholder" src="certrqus.asp" />

    <frame id="nowitbreaks" name="nowitbreaks" src="certrqma.asp" />"



    No frames.



    Anyhow, as you can see, this is as basic as it comes. If I access this page (certrqma2.asp) from IE8 from either the 2008 R2 server or from a Win7 machine, the certrqma.asp frame errors out.  HOWEVER, if I access this same page (certrqma2.asp) from IE8 on XP or Vista, it works fine.  For the record, if I access the original file(s) (e.g. certrqma.asp) directly from 2008 or Win7, it works.  The issue is the desire to use frames.

    Any assistance would be greatly appreciated.

  26. ed martin says:

    I can only get this to work under ie8 and windows 7 if i make it a trusted site and I set the security setting to allow the initialisation of active x controls not marked as safe for scripting. I don’t mind making it a trusted site but I can’t ask my user to enable active x controls not marked as safe for scripting. Any suggestions?

  27. scuttill says:

    regarding my prior post – found the offending lines of code in the Microsoft cert web enrollment pages.

    Look at certsrven-us … for a file called "" – It is this file that we need to make a small change to.

    Inside it, there is a section of code that looks like this (about line 43):

    <Span ID=spnCertEnroll Style="display:none">

      <OBJECT id=’g_objClassFactory’ CLASSID=’clsid:884e2049-217d-11da-b2a4-000e7bbb2b09′>



    <Script Language="VBScript">

      Option Explicit

      Dim g_objEnroll

    I changed it to the following and everything works beautifully – both with and without frames – all O/S’s (tested XP, Vista, Win7, Win2003, Win2008).  Notice I comment out the original <Span><OBJECT>… stuff.

    <!–<Span ID=spnCertEnroll Style="display:none">

    <OBJECT id=’g_objClassFactory’ CLASSID=’clsid:884e2049-217d-11da-b2a4-000e7bbb2b09′>



    <Script Language="VBScript">

      Option Explicit

      Public g_objClassFactory

      Set g_objClassFactory = Nothing

      Set g_objClassFactory = top.document.getElementById("g_objClassFactory_Proxy")

      if g_objClassFactory Is Nothing then

         top.document.body.insertAdjacentHTML("afterBegin","<object id=""g_objClassFactory_Proxy"" classid=""clsid:884e2049-217d-11da-b2a4-000e7bbb2b09"" height=0 width=0></object>")

         Set g_objClassFactory = top.g_objClassFactory_Proxy

      end if

      Dim g_objEnroll

    Thanks Frank for helping get this started.  For anyone else, feel free to use this as you see fit.

  28. Please, not that previous solution won’t work if both parent and child pages are not in the same domain.

  29. ieblog says:

    CertEnroll is SiteLocked and will only work from HTTPS pages by default.

  30. Good news!!! There is a fix available for the issue with frames that several people commented here. Check this other post of mine:

    CertEnroll control won't work when hosted inside a frame/iframe in IE8 (FIX)…/certenroll-control-won-t-work-when-hosted-inside-a-frame-iframe-in-ie8-fix.aspx

  31. Cristian Nunez says:

    Hello, just wondering if you have any advice/example on how to create a certificate request using an existing key stored on the browser.

    In XP, I've used capicom to access the private key from a certificate stored in the browser and xenroll to create the certificate request.  However I haven't found the way to replicate the same behavior with certenroll.

    Any ideas?

    Many thanks,


  32. I have no sample for that, sorry.

  33. Stephen says:


    My code to make requests/imports works fine in Win7 now using my version of the workaround (referring to the parent page to access the object), with a little extra tweaking to make it flexible enough to work both within a frame and as a standalone page.

    However I just came up with another new issue I hadn't tested for before–the certificate apparently can't be imported when its validity period is in the future.  This is going to make things messy for us as we need to issue users their replacement certificates before their current one expires, generally, and to eliminate multiple valid certs, we issue with a validity period starting right after the expiration of the existing certificate.  This has never been a problem with any other browser/OS environment, but now it's been brought to my attention that it may not work in Win7.  Is this a hard setting, or something that can be configured for, or….?

    Any thoughts appreciated.


  34. Stephen says:

    Hi again–

    Haven't seen any response on this question.  Any ideas at all?


  35. Sorry Stephen, I don't know the answer to that without doing some research. I would need to spend time on this, and for that I need a support case. I suggest you open a case with us, Microsoft Technical Support.



  36. Stephen says:


    After weeks of no luck finding any insights about this issue, we did open a case this week.  Three days in and apparently we're still trying to fully get the nature of the problem across….



  37. Well, if I can be of any help, tell whoever is the owner of the case I'm willing to assist if needed.



  38. Stephen says:


    Thanks, we have a premiere incident opened and I've passed your name and offer to the person here to include in our next response on the case.    Is there any additional information we should give if they try to look for your help?


  39. No, thx. I just located your case in our databases and I offered my help personally to the colleague in charge of it.



  40. Philipp Gühring says:

    On XP (and I think on Vista) I was able with CertEnroll to load a renewed certificate (same public key and name, new serial number and expiration date) into IE by calling InstallResponse(). Now with Win7 we get an error message -2146885628 with the same CA code. What is the correct way to install a renewed certificate, for which there is already a private key available? Does it need a special parameter, a different API, or is it not possible at all anymore? Has this functionality been intentionally turned off with Win7 ?

    Additionally, could you please explain, why CertEntroll is delivered as marked not Safe for Scripting? Is it not supposed to be used on websites? Or are trusted sites supposed to run code that is not marked Safe for Scripting? A lot of my users do not want to run code that is not marked as Safe for Scripting. Are there any plans to provide a CertEntroll (alternative) that is Safe for Scripting?

  41. First of all, CertEnroll won't work on XP, only on Vista and later. On XP we use XEnroll.

    Assuming you are using CertEnroll, I don't know why that error -2146885628 a.k.a. CRYPT_E_NOT_FOUND a.k.a. "Cannot find object or property" appears on Win7. I guess you should be able to renew certs, so this may require a MS Technical Support case to debug it.

    The same goes for the "Safe for Scripting". I don't have the answer. Marking a control as "safe for scripting" is an assertion by the author that the control is not capable of being misused to take a destructive action. Installing certificates in user's store is serious business. If someone manages to install e.g. a root CA in our store, and certs issued from that CA are used by untrustworthy sites, we have a problem. So I guess that is why CertEnroll is not marked as being safe. But that would need to be confirmed by our Product Group…

  42. Stanque says:


    I am wondering is there a way to set private key strong protection while creating certificate request using Javascript approach? Can somebody give me some sort of example for this or at least some guide line since i'm not so familiar with the subject (or at least with accessing and handling certificatest programatically). I have looked at msdn documentation and found KeyProtection property of private key object but i'm not so shore how to use it. Thank's in advance.

  43. Gordon says:

    Is it feasible to submit the request to an Enterpise CA from the Javascript instead of C#?

    Thank you,


  44. Yokai says:

    I have successfully implemented this but unless I set the security settings in IE to Low for this site (and make it trusted) then I cannot get the control to run – I receive Object doesn't support this property or method.

    My users are not particularly savvy and so getting this to a state where it will run correctly is important – is this just a matter of signing the control?  (if so – how does one do that) or is there more to this than meets the eye?

    Thanks in advance –


  45. Gordon says:

    >Is it feasible to submit the request to an Enterpise CA from the Javascript instead of C#?

    I found the answer to this, we can call ICertRequest3::Submit Method in javascript to use the DCOM interface for the CA vs HTTP post..


  46. David says:

    How to install PKCS#7 in Smart Card?

  47. You should use a smart card provider when making the request. My sample uses a non-smart card CSP.

  48. David says:

    How to install PKCS7# to Smart Card?Thanks!

  49. Ahamed says:

    Hello Friends,

    I need a help regarding installResponse(4,pkcs7,0,""); With windows 7 I get the following error as

    Access Denied. Kindly do provide details of what need to done for this.

  50.        var objRequest = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509CertificateRequestPkcs10");

           var objCertEnrollClassFactory = new ActiveXObject("X509Enrollment.CX509EnrollmentWebClassFactory");

           var objPrivateKey = this.classFactory.CreateObject("X509Enrollment.CX509PrivateKey");

           var objEnroll = objCertEnrollClassFactory.CreateObject("X509Enrollment.CX509Enrollment");

           // Provide CSP information tp the private key object

           //utilisation du CSP Gemalto

           objPrivateKey.ProviderType = providerType ;

           objPrivateKey.ProviderName  = providerName;

           //  Provide key container name, key length and key spec to the private key object

           objPrivateKey.Length = 1024;

           objPrivateKey.KeySpec = 1; // AT_KEYEXCHANGE = 1

           // Initialize P10 based on private key

           objRequest.InitializeFromPrivateKey(1, objPrivateKey, ""); // context user = 1

           objRequest.Subject = objDn;

           // Enroll


           var sPkcs10 = objEnroll.CreateRequest(1); // XCN_CRYPT_STRING_BASE64 = 1

    Lorsque j'appelle la fonction CreateRequest, j'obtiens l'erreur 80090020 qui signifie "Erreur interne".

    Je me demande si le problème peut venir de la configuration du poste client, ou de la privateKey, ou du CSP (Gemalto) ou du CA ….

    Quelqu'un peu m'aider ?

  51. Irresistibledemon, Désolé, je ne parle pas français…

  52. I say i have a probleme when i use the function : CreateRequest.

    An error 80090020 occured, This error means "Internal Error" but i don't understand which component is the cause source …

    There is a problem with :

    • The navigator (IE7) ?

    • The privateKey Object ?

    • The CSP ?

    • other ?

  53. Hi Irresistibledemon,

    I cannot tell why that error happens exactly without debugging the issue. And for that I would need you to create a Technical Support Case so I can assist you. In any case, note that IE7 has some issues with CertEnroll:

    Error message when a user uses Internet Explorer 7 to open the certificate enrollment Web page to install an end entity certificate on a Windows Vista-based client computer

    Why aren't you using IE9? (or IE8 if you are on XP?) It is way better than IE7.



  54. Cristian says:

    On IE10 and IE11 (Windows 7 and 8) insertAdjacentHTML does not add the necessary object to the top frame, therefore the workaround for windows 7 does not work anymore. In fact, even if I hardcode the object on the main frame it can not be accessed by getElementById.

    Does anyone knows a solution for this?