使用TSA URL和Java API进行时间戳

时间:2015-01-22 09:51:33

标签: java security digital-signature timestamping rfc3161

任何人都可以帮助我理解在为签名加时间戳时使用的流程和Java API。

我需要使用Java API使用TSA url“http://timestamp.globalsign.com/scripts/timstamp.dll”对文件进行签名并对其加上时间戳。

我可以使用java.security API对文件进行签名,但无法为其加时间戳。

1 个答案:

答案 0 :(得分:6)

你的问题有点广泛......我会给你一些信息,我希望它会指出你正确的方向。

问题是您希望使用时间戳服务来使用其中的服务执行时间戳签名:http://timestamp.globalsign.com/scripts/timstamp.dll

首先,这项服务是Time-Stamp Protocol (TSP) RFC3161编译,请查看RFC definition here,以便清楚了解其工作原理。

任何我认为你正在寻找一个java代码示例,所以下面我给你一个示例代码,它使用RFC3161的时间戳服务器执行时间戳签名。

此示例中的步骤基本上是:

  1.   

    首先创建时间戳请求,然后将请求发送给   服务,最后阅读回复。

         

    时间戳请求具有以下定义:

    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  }
    
         

    正如您所看到的那样只需要messageImprint,其余的都是   可选的取决于你的tsp服务提供给你的选项。

  2.   

    第二步是使用POST方法发送此时间戳请求   指定为Content-type http-header:   application/timestamp-query

  3.   

    最后一部分是解析响应并获取时间戳令牌。

  4. 所以这是代码:

    所有在一起:

    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;
        }
    }
    

    请注意,我在示例中使用了bouncycastle API

    希望这有帮助,