How to Create a Digital Signing Solution with Only JavaScript

Important-er updates: Nothing below works anymore. Check this article.

Important updates: this code won’t reliably work anymore. If you don’t need smartcard support, use the experimental web crypto API. If you need smartcard support, you’d need an extra plugin, e.g. this one. You can read a detailed analysis of the browser-smartcard interaction here.

It is sometimes required to have the user sign a text in order to certify that he is the one who has done the operation. For example, in an e-banking software, the user might have to sign a text describing the transaction (“Transfer 300 dollars to IBAN xxxxxxxxx”), or sign a request for a governmental eService. This could be achieved by a java-applet, but as JRE owners are not a majority, it is preferable to use other ways.

Of course, the preconditions are, that the user has a digital signature, issued by a CA, and has followed the CA’s manual for installing the certificate in a browser. If these steps are not completed successfully, the solution below wouldn’t work.

Also, note that this uses PKCS7 (java developers: use bouncy castle to verify it), instead of the XAdES standard. Internet Explorer has support for XAdES, but FireFox doesn’t.

Let’s see a simple HTML page that should sign a given text:

<script src="sign.js" type="text/javascript"></script>

<input id="text" type="text" />
<input onclick="signDigest(document.getElementById('text').value);" type="button" value="Sign" />

and then the JavaScript itself:

(Update: the code is now available on GitHub – js-signer)

function signDigest(text)
window.event.cancelBubble = true;

var dest = sign(text); //TODO
return dest;

// CAPICOM constants
var CAPICOM_E_CANCELLED = -2138568446;

function IsCAPICOMInstalled()
if(typeof(oCAPICOM) == "object")
if( (oCAPICOM.object != null) )
// We found CAPICOM!
return true;

function FindCertificateByHash()

// instantiate the CAPICOM objects
var MyStore = new ActiveXObject("CAPICOM.Store");
// open the current users personal certificate store

// find all of the certificates that have the specified hash
var FilteredCertificates = MyStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, strUserCertigicateThumbprint);

var Signer = new ActiveXObject("CAPICOM.Signer");
Signer.Certificate = FilteredCertificates.Item(1);
return Signer;

// Clean Up
MyStore = null;
FilteredCertificates = null;
catch (e)
if (e.number != CAPICOM_E_CANCELLED)
return new ActiveXObject("CAPICOM.Signer");

function sign(src)
if(window.crypto &amp;&amp; window.crypto.signText)
return sign_NS(src);

return sign_IE(src);

function sign_NS(src)
var s = crypto.signText(src, "ask" );
return s;

function sign_IE(src)
// instantiate the CAPICOM objects
var SignedData = new ActiveXObject("CAPICOM.SignedData");
var TimeAttribute = new ActiveXObject("CAPICOM.Attribute");

// Set the data that we want to sign
SignedData.Content = src;
var Signer = FindCertificateByHash();

// Set the time in which we are applying the signature
var Today = new Date();
TimeAttribute.Value = Today.getVarDate();
Today = null;

// Do the Sign operation
var szSignature = SignedData.Sign(Signer, true, CAPICOM_ENCODE_BASE64);
return szSignature;
catch (e)
if (e.number != CAPICOM_E_CANCELLED)
alert("An error occurred when attempting to sign the content, the errot was: " + e.description);
return "";

And that should do the stuff – the signed text can be sent to the server, where it can be verified.

P.S. One important note when verifying afterward – Internet Explorer uses UnicodeLittleUnmarked (UTF-16LE) to encode the signed data, before signing it. So when verifying, use this encoding.

P.P.S. I have extracted the code from this post into a github project – js-signer

112 thoughts on “How to Create a Digital Signing Solution with Only JavaScript”

  1. Well, it’s pretty much all in the code above – just copy-paste it in an .html file and you have the demo. But have in mind that you must have a real signature, otherwise browsers give errors.

  2. IE gives this error: “An error occurred when attempting to sign the content, the error was: Automation server can’t create object”

    Ever seen such? 🙂

  3. Yes. In order to sign successfully (with both IE and Firefox) you need a installed smart card with the digital signature. Self-signed certificates can’t be used with the browsers to sign content. (don’t ask me why 🙂 )

  4. Hi, this jscript is encrypting some given text “Hello” using CAPICOM sertificate?? Ok, so if this is true i would like to get public Key from sertificate, and later use this public key to verify authetntication of used sertificate for encryption(i will encrypt the same text “Hello” but this time with public key and compare both encriptions). Is there any chance for that???


  5. I didn’t quite get your idea, but getting the public key from the encrypted message will be a server-side action, about which I will blog tomorrow (stay tuned). Then you can use it in whatever way you need.

  6. Hi,

    Thanks for your quick replay. My question was how to get public key from CAPICOM certificate.Later use that key to decrypt signed(encrypted) text, and make comparison between original and decrypted text, wich should have some function like verification.

    P.S is there any chance to convert your Java code from your newest blog to C#?


  7. Well, I don’t have enough experience with C# to be able to do so – furthermore, I’m not even sure bouncy castle have C# libraries, so you have to ‘translate’ it yourself, and find the appropriate libraries 🙂

  8. hi me again 🙂

    I can’t understand why on some PCs i am able to get Certificate and sign text and on the other PCs i am get error (Error in reading DLL)????

    when i was Debuging I found that this error occurs in the next two lines.

    var SignedData = new ActiveXObject(“CAPICOM.SignedData”);
    var TimeAttribute = new ActiveXObject(“CAPICOM.Attribute”);

    Thanks for your time and previous responses.

  9. Hm, that would probably be due to unsuccessfully installed smart-card software (Charismatics, for instance). Check the installation procedure from the signature vendor.

  10. Thanks i instaled CAPICOM on all PC’s where i was not able to get theirs certificate, and that solves my problem, now it’s working exelent.
    Thanks again for your help.

  11. This is good but i need only Secure email signature from etoken can u tell me the javascript code for that

  12. Whether it is SmartCard, eToken or self-signed certificate , it doesn’t matter, as long as the browser is set-up to locate them.

  13. Hi.

    Thanks for this valuable article.I wanted to know the signed output length of your code.I am getting morethen 3000 char ,even for a 15 char input.

    Thanks and regards..


  14. Thank you for your response.I wanted to convert this output into pdf417 barcode ,2D. Pdf417 is supproting upto 1800 ascii character only.

    Is there any way to compress the output to reduce the number of characters?.Or please suggest alternate for capicom ,to sign at client side.

    Thanks and Regards.

  15. Thank you for your reply.

    The barcode should contain the SignedData.Sign methods output.I am implementing in application.The content of the barcode should be used for signature verification in future.



  16. Well, then extract the publicKey and put it in the barcode. Should suffice.
    But the PKCS7 contains much more information, hence the big size.

  17. Thanks you for Reply
    I created code for reading etoken code is working fine on local host but when i access page from IIS this is not working What i have to do for that.

  18. “Whether it is SmartCard, eToken or self-signed certificate , it doesn’t matter, as long as the browser is set-up to locate them.”
    How to set upi IE to locate SmartCard so that user can enter pin and then use cert in this js

  19. It depends on the smart card software. It should include detailed manual on how to enable it on each browser.

  20. You are missing “strUserCertigicateThumbprint”, where is this created? What should go here?

  21. Thanks a lot Bozho.

    >Could you copy-paste your question at > – I’m not sure how this old >version of the blog will continue to live, so it’d be better >if I answer you on the other one.

    The question I posted on the other blog:
    I tried this code and works perfectly. I was searching for the same results and the code looks great.
    The problem is the signer.sign result. The signature happens to be @ 2292 bytes. I think it is too long. We are used to hash the data with SHA1 (40 bytes) and sign with RSA 1024 key. The resulting signature is 128 bytes (172 after BASE64).
    Can you please tell me how to resolve this issue so that the sign is 172 bytes long (BASE-64). This is the only thing that is holding us to use the code.
    Thank you for this awesome post.

    I studied on another post about the PKCS#7 format:

    Can we extract the last 128 bits of the PKCS#7 output (from the CAPICOM sign method) to get only the digital signature?

    Thank you again.

  22. Can we extract the last 128 bits of the PKCS#7 output (from the CAPICOM sign method) to get only the digital signature?

  23. Your JS to sign is good.
    I read also “How to obtain signer’s details from a JavaScript signed data” and I’ve seen that this operation is done on a server and is Java. What I need is to verify a signed message given back to me on my computer. Si I need a JS to obtain signer’s details, Is it possible?

  24. I don’t know. But you can send it to the server to obtain the details, and send the details back (with ajax, perhaps)

  25. This looks good for FireFox and IE.
    But will it work in Chrome or Safari?
    I don’t see support there for crypto.signText().

  26. Alas it won’t work there. If you want a completely portable signing solution, you’ll need a Java applet. But it has its drawbacks.

  27. Hello,
    Thanks again for a great app.
    The app runs well where on a developer machine where we have installed Visual Studio.
    But when we try to run the app from a machine without a Visual Studio, we get the error: “Automation Server Can’t create Object”.
    Do we need to install some other application on the client machine to remove this error? or what configuration change we need so that the application works properly on any client?

  28. Update:
    It worked. WOW.
    The solution is to register capicom.dll on the client machine.

    Thanks Bozho. Love…

  29. Bozho,

    The code is working fine in 32 bit Server OS. But there are issues in running in CAPICOM in 64 bit OS.
    Please, can you suggest changes in the code to run in say a .Net with native .Net code instead of COM based code?

    Thank you. I must again say this is a great utility.

  30. We need to develop our own CAPICOM in order to run this Javascript code on a X64 machine.
    Please share your knowledge if someone is already working on this.

  31. Hi,
    I have started looking at crypt32.dll for possible replacement of CAPICOM.
    Can you tell me if your Javascript code will work with crypt32 if we just replace procedure calls to match crypt32 function names to do the same thing as in CAPICOM?

  32. On May 19, you replied:
    @Nitin Nanivadekar Well, you can hash the hash of the result either through javascript (, or send it to the server and hash it there (using MessageDigest)

    This went over my head.
    I have a requirement of extracting only the 172 characters of the digital signature (Base64 encoded) out of about 4164 characters that result from the code – var szSignature = SignedData.Sign(Signer, true, CAPICOM_ENCODE_BASE64);

    Also, szSignature is getting some newline characters from the result.
    Admin, Can you please suggest how to get the right digital signature only?
    is there any way, like extracting the last 172 characters from szSignature?

  33. I’m sorry for not being helpful, but I wrote this code 1.5 years ago and right now I’m busy to look it again and remember what’s being done.

  34. Great post!!
    I was looking for a way to implement this! Now, after I’ve done this, is there a way to verify the certificate on the server side using PHP?

  35. Almost certainly there is a way, but I don’t know – haven’t done PHP for a while

  36. Hi Bozho.

    1. Can this code support the much secured SHA2 or 2048 bit keys?

    2. Have you come across a way to read the public key from the USB based key store?

  37. I don’t know, I haven’t used this code for 2 years now. The USB based key-store – it should be the browser’s responsibility to load the keys. If the browser presents the keys, then the above should work.

  38. Hello! Well it`s been a year since last comment, but let`s try.
    I`m desperately looking for a way to sing a File from browser using JS only (well maybe some severside php to put it somewhere on the server).

    The best I can think of is something like emulation of real process.

    User uploads file, we with serverside scripts (e.g. php) count its hash than user signs it.
    What are the pros and cons I can`t see, and I`ll gladly try some other methods.

  39. For files we used Java applets, to allow signing on the client. With JS it seems that a server should participate and send the hash for signing. This is, strictly speaking, not secure, because someone may temper the file during the process, but I think it’s good enough.

  40. I am using this code and I commented two lines. //if(window.crypto &amp;&amp; window.crypto.signText)
    // return sign_NS(src_message); Because I am using IE. I have executed at developemnt environment. It’s fine it’s working and giving certificates to choose and then it gives hash of the given string. but after deploying it is giving error “An eeror occured when attempting to sign the content, the errort Automation server can’t create object”

  41. This code was running excellent when there is visual studio environment in the machine. but in client machine its not working fine and saying the automatic server can’t create object. I have installed capicom dll in the client system also. Help me out

  42. Thank you Bozho for such useful sample code.

    We are actually trying to sign a .pdf file, rather than just text. do you know if there is a way to read a file from the file system (from the browser) and assign it to SignedData.Content?

    Also, your code seems to correct for it, but I am having the same problem as a user above. this line:

    var FilteredCertificates = MyStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, strUserCertigicateThumbprint);

    Throws the following error:
    “‘strUserCertigicateThumbprint’ is undefined”

    can we just pass null for this? where did you define it?

    thank you

  43. Hi,

    Unfortunately, I did that years ago, and I don’t remember the details.

    You can’t sign a PDF, that’s for sure. But you may get a hash of the PDF and sign that – should work, I guess.

  44. Hi,

    Can i use Sha2 encryption?

    How can i validate the certificate is up to date?


  45. Hi Bozho

    I know I made ​​the code a few years ago, but maybe you can help me. I could adjust your code to only read data from the client’s digital certificate?

    I’d like to read this data and use them to control a login page of a website.


  46. Well, simply use an identifier from the certificate you obtained and store it in the db, then check it and perform the login.

  47. Hi Bozho

    Tanks.:-) Is it, but you have an example code? For example, where in your code in this post I could take the value of the certificate, eg the name or subject or a particular field?

    I’m “struggling” to adjust the code of the post, but have not figured out how to determine this with Capicom. 🙂

    The idea is exactly that, I would read a value from the database and compare with the value on the digital certificate to allow access to certain pages of the site.

    All help is welcome. 🙂


  48. Hello Dear,

    I want to attached digital certificate with my web page.
    but don’t find anything. I need to decrypt that certificate from token USB device and have to attached with my webpage.

    I had also saw one application which is in ASP.NET where One popup window that come from click on one button called “Select Certificate” but doesnt able to make it in php

    Your Above explain concept I have read properly but it doesnt work when I copy and paste in html.

    Want to ask that CAPICOM library will be a file or it will automatically get its function.

    Please help me here. I had make full R N D in that but didnt find any thing.

  49. Greate Work:) This Code is Working Fine for 32bit Os … Have u Any Idea for 64 bit Os…Pls anybody knows about 64 bit please Share:)

  50. Hi! I understand this is somewhat off-topic but I had to
    ask. Does running a well-established website like yours require a large amount of work?
    I’m completely new to running a blog but I do write in my journal every day.

    I’d like to start a blog so I can easily share my experience
    and views online. Please let me know if you have any kind of ideas or tips for brand new aspiring
    blog owners. Thankyou!

  51. Varieties include traditional metal, gold braces, and clear
    plastic type kinds. Your non verbal movements say much more
    about how you come to feel than your words
    do. We have found that in grading our deals, we were making the best use of our times working on deals that
    had a high chance of closing.

    Also visit my blog; women leans

  52. Have a supply of disposable applicators so clients will always
    have what is needed to sample products without cross contamination from hands,
    eyes, lips, etc. It is right to be informed of the products that we use and consume on our bodies.
    At this online shopping site, you will get variety of cosmetic products from Inglot brand.

    The European Commission on Endocrine Disruption disclosed that there is strong evidence of its effect as a human disruptor.

    A Butulanium bacterium produces seven types of poisons that operate in a similar way.
    00 A light emulsifying kit enriched with effective plant extracts to lighten the color of the
    skin and improve the texture without affecting moisture level of the skin. Clientele is that the creation of an innovative mind that belongs to Pat Riley.

    It’s the eyeshadows that most demonstrate the lack of color distribution. Photos and important information can be found on the official Facebook page.
    Below are a few suggestions that will help you find the best cosmetics for your sensitive skin. Or do you think they are
    going to opt to use the cheapest ingredients available on the market to ensure optimal
    profit for their business. – Hair care products
    accounted for more than 25% (expected) of the total cosmetics &
    personal care market in 2007. Epsom salt soak for infected cuts:
    One cup of unboiled warm water with two table
    spoons of Epsom salts plain soak for twenty minutes twice a day till infection is gone.
    But it is always crucial to consider what products you are selling; your complete success depends on proper
    selection and adequate know how. Often online stores
    provide great discounts on products in order to be competitive.

  53. I really like what you guys are usually up too.

    This type of clever work and exposure! Keep up the excellent works guys
    I’ve added you guys to my personal blogroll.

  54. We all face high electric bills during those long summer months and wish there
    was a way to reduce them. I can see the white sand
    beaches, feel the warm ocean water, and smell the fragrant breeze.
    The second quote in the first image is also very important.

    Visit my blog :: powerbank

  55. my application is in ASP.NET and i want to provide login using digital certificate.
    I want to read digital certificate info and store it in database then i have to provide login with digital certificate.I am trying to get certificate info but i coundnt using java-script. please help

  56. Thanks for the a new challenge you have exposed in your text.
    One thing I’d prefer to discuss is that FSBO human relationships are built
    eventually. By presenting yourself to owners the first weekend break their FSBO is announced, prior to masses start out calling on Thursday, you create
    a good network. By mailing them resources, educational materials,
    free reports, and forms, you become an ally. If you take a
    personal affinity for them plus their circumstance, you make a solid
    link that, oftentimes, pays off once the owners opt with a realtor they know in addition to trust — preferably

    my blog: promoting gold

  57. Thank you for some other informative web site.

    Where else may just I get that type off info written in such an ideal method?
    I’ve a challenge that I am just now operating on, annd I’ve bedn at the look out for such info.

  58. Of course, if you want to build teamwork, you will definitely want to practice together.
    So, strap on all your paintball load and gear up those paintball
    guns! Work on defensive and offensive strategies, code words,
    “what-if” scenarios, and more. Learn from the opposition along
    with your personal teammates. Carefully discover other paintball athletes to develop new and successful approaches for upcoming game titles.
    Does the opposite team discuss more than your crew does?
    Do they really appear to be much more arranged? Focusing on how your foes come together may help increase your team’s overall performance.
    Take a look at your opponents paintball gear and see if your team
    is lacking in that area. This will greatly result your
    game play

    Here is my blog post :: paintball gun (

  59. Howdy this is somewhat of off topic but I was wanting to know if
    blogs use WYSIWYG editors or if you have to manually
    code with HTML. I’m starting a blog soon but have no coding expertise so I wanted to get
    advice from someone with experience. Any help would be
    greatly appreciated!

  60. Since the software is downloaded and installed
    on your home PC, you can access it only from your own computer.
    By choosing this set, you will always have a tiny piece of Las Vegas Nevada to yourself.

    The Prison Tycoon series is just awful, I know it
    sounds like it might be fun but believe me it isn’t.

  61. So a search by a new visitor for a product that Amazon doesnt sellwhich results in a sale through the merchantmeans
    that Amazon has acquired a new customer. While not usually endorsed
    by the product manufacturer these hacks should not be confused with more nefarious computer hacking.
    Make sure your photographer understands your budget.

  62. hi!,I like your writing so a lot! share we communicate extra approximately your article on AOL?
    I need an expert in this space to unravel my problem.
    Maybe that’s you! Taking a look ahead to peer you.

  63. This is the best fotografi matrimonio napoli in this world.
    Mainly it covers the actual Microsoft windows and also the Microsof company servers.
    Children and grandchildren can be shown the photographs of the wedding ceremony.

  64. Hello Bozho!
    What are the requirements apart from the installation of the certificate to the code work? I tried it in firefox and says “Sorry, your browser is not supported”. In IE tells me “An error occurred When attempting to sign the content, the mistake was: Automation server can not create object”. I need to read a certificate from the client to sign a register to be Take away the server.I installed the certificate from the browser, just that. I would appreciate your response.

  65. Wonderful blog! Do you have any tips and hints for
    aspiring writers? I’m hoping to start my own site soon but I’m a
    little lost on everything. Would you advise starting with a free platform like WordPress or go for a paid
    option? There are so many choices out there that
    I’m totally confused .. Any recommendations? Appreciate

  66. This iis a good tipp especilly to those new to the blogosphere.

    Simple butt very accurate information… Thanks for sharing his
    one. A must read post!

  67. Dear Bozho!!!!!

    When i am using this window.crypto.signText(src, “ask”); javascript funtion tht will throw return error:internalError..error.So i was find this solution == call to crypto.signText returns “error:internalError” if the issuer of your certificate “is not trusted”..Plz help me where is location of trusted certificate in mozila firefox??
    I am using mozila firefox v.31 and where is insall trusted certificates mozila or server(tomcat(path))??

  68. Dear Bozho!!!!!

    var s = window.crypto.signText(src, ‘ask’) this javascript funtion return always diffrent signature key on same device..
    plz help me where is the problem..???

  69. Hi,

    Could you please tell me How to authenticate Digital Certificate Inside Usb e-token using Capicomjs ?

  70. I Have gone through the article it is excellent one need small help by using above code I am able to get pin prompt only once I need when ever I select certificate need to get pin prompt Could you please help me out

  71. HI ,

    I have written the code in button click when ever I click button I need pin prompt , but our code showing only first time if I close the browser and start newly again it showing

  72. Hi Thanks for your post and it is really helpful,I am able to sign the hash of my pdf (which i am getting after adding signature at C# end server side) then I am signing this has using CAPICOM at client side and once i got my PKCS7 i am embedding this in pdf maker at server side then after whole process I am getting signature invalid (however other details are there only document is altered was showing) please suggest ,
    thanks in advance.

  73. HI ,

    Could you please help to resolve the issue stopped the deployement

    I followed your code fro smart card pin prompt it is working in all our clients machine in one system it is not working throwing error like “Automation server can’t create object”

    I verified his system setting are similar to my system capicom dll existed in his too and ever thing seems to be same

    Could you please suggest what are other steps we have to follow

  74. I have checked the code its working but I require to fetch Details of e Token such as Owner Name, Expiry Date and Serial No etc. .. Can you please help on the same.Please its very urgent.

  75. Thank you for any other great article. The place else could anyone get that
    type of info in such a perfect method of writing? I’ve a presentation subsequent week, and I’m on the search
    for such info.

  76. My project is “Digital signature verification in local area network using ASP.NET and C#”. Actually i am using etoken for user authentication and digital signature for signing the pdf or word or excel file.How to detect the etoken in the webapplication using javascript. And how to extract the digital certificate from the etoken. And what type of server shall I use for this project. Kindly reply to this post.

  77. hi,
    I am doing my project on digital signature verification for local area network using eToken.
    what type of database can I use to store the extracted information such as public key,private key.. etc i from digital certificate presented in etoken?. whether we can store pdf file which has to be signed in etoken?. how to load pdf file into database?
    plssssss reply to me

  78. HI,
    I wanted to sign text using private key of the user’s smartcard using javascript. I followed your code and while signing i am getting error like-“Automation server can’t create object”. I installed smart card as well as capicom.dll in client machine.Please let me know the solution.

  79. For browser based signing scenarios, one such free Chrome extension available is Signer.Digital chrome extension. Windows setup may be downloaded from
    Installing this host and restarting Chrome will automatically add [Signer.Digital Chrome Extension]

    The actual working of this extension is illustrated here

    Javascript code may be referred from

  80. Hello ,this post is very good but I want to generate sign on chrome , capicom works only on IE, can you help me?

Leave a Reply

Your email address will not be published.