How to Create a Digital Signing Solution with Only JavaScript

April 16, 2009

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;&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.

If you find the content interesting, you can subscribe and get updates


68 Responses to “How to Create a Digital Signing Solution with Only JavaScript”

  1. Can we see a demo of this?

  2. 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.

  3. 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? :)

  4. 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 :) )

  5. 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???


  6. 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.

  7. [...] to obtain signer’s details from a JavaScript signed data By bozhobg In a previous post I described how to sign data with only javascript. Now, this data should be used on the server side [...]

  8. Check this out –

  9. 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#?


  10. 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 :)

  11. 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.

  12. I forget to say that all PCs in my network have certificate by same Issuer.

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

  14. 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.

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

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

  17. 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..


  18. Yes, this is normal. The whole certificate data is encoded in base64, so it’s fine.

  19. 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.

  20. What information should the barcode contain?
    You can extract whichever part of the PKCS7 you wish – check this post:

  21. 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.



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

  23. Thank you,

    I will do in that way.



  24. Thank You,

    I will do based on your suggession..



  25. 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.

  26. “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

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

  28. [...] How to create a digital signing solution with only JavaScript [...]

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

  30. 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.

  31. @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)

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

  33. [...] a previous post I described how to sign data with only javascript. Now, this data should be used on the server side [...]

  34. 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?

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

  36. I will try calling CAPICOM activex from JS.

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

  38. 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.

  39. 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?

  40. Update:
    I tried to run the SDK at to install the SDK.
    But the error “Automation Server Can’t create Object” is still showing up.
    Please help.

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

    Thanks Bozho. Love…

  42. gr8!!
    code worked fine for me.

    but i have dought. what that IsCAPICOMInstalled() method does.

  43. 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.

  44. I have no idea about 64 bit.. If you find a way ‘through’, please share.

  45. 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.

  46. 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?

  47. I don’t know. Give it a try.

  48. Nitin,

    This code will work fine on X64 bit machine. you need to install CAPICOM on that machine.

  49. 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?

  50. 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.

  51. 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?

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

  53. 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?

  54. 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.

  55. 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.

  56. 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.

  57. 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”

  58. 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

  59. 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

  60. 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.

  61. Hi,

    Can i use Sha2 encryption?

    How can i validate the certificate is up to date?


  62. 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.


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

  64. 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. :-)


  65. 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.

  66. can anyone will help me out here.

  67. [...] (How to Create a Digital Signing Solution with Only JavaScript) [...]

  68. [...] the use of smart cards and digital signatures. I’ve already shared my experience with signing with javascript and then verifying the signature on the server side (with [...]

Leave a Reply