How to obtain signer’s details from a JavaScript signed data

In a previous post I described how to sign data with only javascript. Now, this data should be used on the server side for something. Here is how a Java developer can extract the signature details, and verify whether the content received from a form is really what has been signed. The general scenario is – a user submits a form, the data from which he signs. Then on the server the submitted data should be verified against the signed (PKCS7) data.

One needs the Bouncycastle libraries and apache commons codec:
commons-codec-1.3.jar
bcprov-jdk16-143.jar
bcmail-jdk16-143.jar

package com.materna.remedy.plugins;

import java.security.Security;
import java.security.cert.CertStore;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class CertificateDataExctractor {
	private Map<String, Object> extractInfos(String base64EncodedPKCS7,
			String contentString, boolean isIe) {
		
		try {
			byte[] data = Base64.decodeBase64(base64EncodedPKCS7.trim().getBytes());

			Security.addProvider(new BouncyCastleProvider());

			CMSSignedData signedData = new CMSSignedData(data);

			if (signedData.getSignedContent() == null) {
				byte[] contentBytes;
				if (!isIe) {
					contentBytes = contentString.getBytes();
				} else {
					contentBytes = contentString.getBytes("UnicodeLittleUnmarked");
				}

				CMSProcessable cmsProcesableContent = new CMSProcessableByteArray(
						contentBytes);
				signedData = new CMSSignedData(cmsProcesableContent, data);
			}

			CertStore certsStore = signedData.getCertificatesAndCRLs(
					"Collection", "BC");
			SignerInformationStore signersStores = signedData.getSignerInfos();

			boolean verified = true;
			boolean validCertificate = true;
			Map<String, Object> signerData = null;

			for (Iterator<SignerInformation> iter = signersStores.getSigners()
					.iterator(); iter.hasNext();) {
				SignerInformation signer = iter.next();
				// emulate(signer);

				Collection certCollection = certsStore.getCertificates(signer
						.getSID());

				if (!certCollection.isEmpty()) {
					X509Certificate cert = (X509Certificate) certCollection
							.iterator().next();

					try {
						if (!signer.verify(cert.getPublicKey(), "BC")) {
							verified = false;
						}
					} catch (Exception ex) {
						ex.printStackTrace();
						// if this is an attempt to verify it assuming Firefox,
						// try assuming IE. If it is already IE - the
						// verification doesn't pass
						if (!isIe) {
							return extractInfos(base64EncodedPKCS7,
									contentString, true);
						}
						verified = false;
					}

					// If this is the last signer in the chain, obtain the data
					if (!iter.hasNext()) {
						signerData = extractSubjectInfos(cert);
					}
				}
			}
			return signerData;
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}

	}
}

And of course, you provide your own implementation of getSubjectInfos method, putting whatever data you need from the certificate in the Map.

15 Responses to “How to obtain signer’s details from a JavaScript signed data”

  1. 使用CAPICOM实现证书管理 « 出家如初,成佛有余 Says:

    […] How to obtain signer’s details from a JavaScript signed data […]

  2. Sujita Says:

    I used crypto.signText to get signed data and then pass that signed data to above mehtod i got following error

    org.bouncycastle.cms.CMSException: message-digest attribute value does not match calculated value
    at org.bouncycastle.cms.SignerInformation.doVerify(Unknown Source)
    at org.bouncycastle.cms.SignerInformation.verify(Unknown Source)
    at org.bouncycastle.cms.SignerInformation.verify(Unknown Source)
    at test.CertificateDataExctractor.extractInfos(CertificateDataExctractor.java:64)
    at test.CertificateDataExctractor.main(CertificateDataExctractor.java:123)

    can u tell me what i am doing wrong

  3. Ashish Says:

    I am signing with capicom activex and java script at client end.At server end,i need to convert that signature into pkcs7 compatible format.Can anybody give me any suggestions..

  4. Ashish Says:

    can you give .net compatible code to do this??

  5. My Blog » 使用CAPICOM实现证书管理 Says:

    […] How to obtain signer’s details from a JavaScript signed data […]

  6. Nikolai Kosev Says:

    1. Principal p = cert.getSubjectDN();

    2. String tmpSDN = p.getName();
    On row 2 you can get the SubjectDN from the signer’s certificate where you have all the data about the signer( Name, email, etc.)

    3. int beg = tmpSDN.indexOf(“CN=”);
    4. //int end = tmpSDN.indexOf(“,E=”);
    5. int end = tmpSDN.indexOf(“,L=”);
    6. String signerName = tmpSDN.substring(beg+3, end);
    On row 6 you get the name of the person wich the certificate belong to

  7. sena redyy Says:

    Can i get publickey information through javascript… please i am new to this

    thank you

  8. Odpryski na temat podpisywania PDF « Wiadomości o technologiach IT Says:

    […] Odebranie po stronie Java podpisanego dokumentu – https://bozhobg.wordpress.com/2009/07/02/how-to-obtain-signers-details-from-a-javascript-signed-data/ […]

  9. marykay Says:

    Way cool! Some very valid points! I appreciate you writing this write-up and the
    rest of the site is also really good.

  10. women leans Says:

    And of course it has the ever popular,collection of coins.
    ) Squeeze the flyer’s ankle (spotter) – Squeeze the flyer’s ankle for additional support, which will
    make the stunt more secure. When two people are speaking, there
    is an unstated rule that their eyes are seen as the imaginary
    line of equality.

  11. bouncy castles Says:

    This is very interesting, You’re a very skilled blogger.
    I’ve joined your feed and look forward to seeking more of your magnificent
    post. Also, I have shared your website in my social networks!

  12. bouncy castle hire bedfordshire Says:

    Jones stimulations have been around for a long time, we do allocate of things, for example, bouncy mansion employ Bedford
    and go karts, rodeo bulls and numerous all the more energizing things!
    Jones excitements have open risk protection for bouncy manor
    contract Bedford, in the event that you ever need to book a bouncy château enlist Bedford simply ring 07145897163 for
    a speedy quote today!

    Bouncy château employ Bedford likewise give things, for example,
    pop corn, confection floss and slush puppy’s! also we additionally give rodeo bulls,
    grown-up bouncy stronghold for the grown-ups! normal, we all know you would love to skip on a stronghold!
    that is the reason we’ve got one! Jones amusements has all that, you approach we can get it for you!
    Simply call us and we will see what we can do to bail you out.
    Did you know we additionally do petrol motored go karts?
    Everyone cherishes these thus if you! their truly extravagant however so please uncovered that as a top priority, the
    petrol motored run karts likewise accompany an expanded track and 4 jars of petrol every go kart!
    so in the event that you need us at your destiny simply visit our
    site or simply ring us!!

    bouncy stronghold contract Bedford additionally cover the whole nation, not simply bouncy mansion enlist Bedford we do surrey,
    henlow, Stevenage, London, surrey and numerous more! Bouncy manor enlist Bedford
    likewise do fun reasonable ground rides and that is additionally for contract!
    the greater part of our bouncy château procure Bedford costs range from £20 to £500!
    that eventual our humongous 30ft slide we have for contract and actually for fiats!
    so on the off chance that you wish to book a bouncy château employ Bedford simply get on the blower
    today to one of our counselors TODAY!!!!

    see what I did their? “blower” hahaha this is on account of a blower controls a mansion. Book a bouncy palace employ Bedford

  13. MadhavN Says:

    Hi,

    signer.verify(cert.getPublicKey(), “BC”),

    the above line always fails. i am not able to debug where exactly is an issue. So can guide me what the signer object contains and how the verification is happening with public key. thanks in advance

  14. fakhir Says:

    is there any possibility to run a digital signature in chrome browser please suggest me something
    thanks

Leave a reply to Sujita Cancel reply