Timestamping using TSA URL and Java APIs

被刻印的时光 ゝ 提交于 2019-12-21 02:55:26

问题


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.


回答1:


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,



来源:https://stackoverflow.com/questions/28085619/timestamping-using-tsa-url-and-java-apis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!