Timestamping using TSA URL and Java APIs
Asked Answered
C

1

2

Can anyone please help me in understanding the process and Java APIs used while timestamping a signature.

I need to sign a file and timestamp it using TSA url "http://timestamp.globalsign.com/scripts/timstamp.dll" using Java APIs.

I am able to sign the file using java.security APIs but unable to timestamp it.

Chrystel answered 22/1, 2015 at 9:51 Comment(0)
E
8

Your question is a bit broad... I will give you some info which I hope it will point you on the right direction.

The thing is that you want to use a timestamp service to perform a timestamp signature using the service there: http://timestamp.globalsign.com/scripts/timstamp.dll.

First of all this service is an Time-Stamp Protocol (TSP) RFC3161 compilant, take a look on the RFC definition here to get a clear idea about how this works.

Anywise I think that you're looking for a java code example, so below I give you a sample code which performs a timestamp signature using a timestamp server of RFC3161.

Basically the steps in this sample are:

  1. First create the timestamp request, then send the request to the service and finally read the response.

    The timestamp request has the follow definition:

    TimeStampReq ::= SEQUENCE  {
       version                      INTEGER  { v1(1) },
       messageImprint               MessageImprint,
       --a hash algorithm OID and the hash value of the data to be time-stamped
       reqPolicy             TSAPolicyId              OPTIONAL,
       nonce                 INTEGER                  OPTIONAL,
       certReq               BOOLEAN                  DEFAULT FALSE,
       extensions            [0] IMPLICIT Extensions  OPTIONAL  }
    

    As you can see only the messageImprint it's required, the rest are optional an depends on the options of your tsp service gives to you.

  2. Second step is to send this timestamp request using POST method an specifying as a Content-type http-header: application/timestamp-query.

  3. The last part is to parse the response and get the timestamp token.

So here is the code:

All together:

import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.Date;
import java.util.Random;

import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1StreamParser;
import org.bouncycastle.asn1.DERBoolean;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.tsp.MessageImprint;
import org.bouncycastle.asn1.tsp.TimeStampReq;
import org.bouncycastle.asn1.tsp.TimeStampResp;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.tsp.TimeStampResponse;
import org.bouncycastle.tsp.TimeStampToken;

public class TimeStampGenerationSample {

    public static void main(String args[]) throws Exception{

        // for this sample we will use SHA1 to perform the hashes
        // however feel free to use another algorithm since sha1 is weakness
        String sha1Oid = "1.3.14.3.2.26";
        // data to be timestamped
        byte[] data = "some sample data... or your signature...".getBytes();

        // perform the hash of your data
        byte[] digestData = MessageDigest.getInstance(sha1Oid, new BouncyCastleProvider()).digest(data);
        // generate random data to perform your ts, it's optional depends on your ts service
        Random rand = new Random(new Date().getTime()); 
        String nonce = BigInteger.valueOf(rand.nextLong()).toString();          
        // require cert optional (default false... so use false)
        boolean requireCert = false;
        // timestampPolicy it's an oid to identify a policy, if it's required
        // must be provided by your ts service... it's optional so we put null
        String timestampPolicy = null;      

        TimeStampReq ts_req = createTimeStampRequest(digestData, nonce, requireCert, sha1Oid, timestampPolicy);

        // the data to be send to the service
        byte[] dataToSend = ts_req.getEncoded();

        // simply send your data using POST method
        // don't forget to specify http-header content-type as "application/timestamp-query"
        byte[] response = // send the request as you want
        // parse the response 
        ASN1StreamParser asn1Sp = new ASN1StreamParser(response);
        TimeStampResp tspResp = new TimeStampResp((ASN1Sequence)asn1Sp.readObject());
        TimeStampResponse tsr = new TimeStampResponse(tspResp);
        // and get the timestamp token :)
        TimeStampToken token = tsr.getTimeStampToken();
    }

    /**
     * Create the timestamp request
     * @param hashedData
     * @param nonce
     * @param requireCert
     * @param digestAlgorithm
     * @param timestampPolicy
     * @return
     * @throws TimeStampGenerationException
     */
    public static TimeStampReq createTimeStampRequest(byte[] hashedData, String nonce, boolean requireCert, String digestAlgorithm, String timestampPolicy) throws TimeStampGenerationException {

        MessageImprint imprint = new MessageImprint(new AlgorithmIdentifier(digestAlgorithm), hashedData);

        TimeStampReq request = new TimeStampReq(
                imprint, 
                timestampPolicy!=null?new DERObjectIdentifier(timestampPolicy):null, 
                nonce!=null?new DERInteger(nonce.getBytes()):null, 
                new DERBoolean(requireCert), 
                null
        );      

        return request;
    }
}

Note that I use bouncycastle API in the sample.

Hope this helps,

Expiratory answered 23/1, 2015 at 14:7 Comment(2)
Thanks a lot @Expiratory for your reply......but I have already gone through this article.The problem with me is that I have to use just Java APIs and no external jars or APIs for the same.Could you please let me know any other way for resolving the same.Chrystel
through this article? what do you mean... anyway if you want to implement the TimeStampReq structure element and the other related asn1 objects without bouncycastle... read the RFC specification an have luck implementing it...Expiratory

© 2022 - 2024 — McMap. All rights reserved.