java - 使用 TSA URL 和 Java API 的时间戳

标签 java security digital-signature timestamping rfc3161

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

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

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

最佳答案

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

事情是你想使用时间戳服务来使用那里的服务执行时间戳签名:http://timestamp.globalsign.com/scripts/timstamp.dll

首先,此服务是一个时间戳协议(protocol) (TSP) RFC3161 编译器,查看 RFC definition here以清楚了解其工作原理。

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

基本上这个示例中的步骤是:

  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.

代码如下:

一起:

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

希望对您有所帮助,

关于java - 使用 TSA URL 和 Java API 的时间戳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28085619/

相关文章:

java - 从 Java Applet 调用 JavaScript 函数的最佳方式

java - 我们可以挑出一个警报(例如 "Web Browser XSS Protection Not Enabled")并在 ZAP 代理中重新运行吗

c - 返回 libc - 非法指令

timestamp - XP/Vista上的数字签名时间戳 "not available",导致验证失败

java - 在 Android 中签名数据并在 python 中验证它

java - setVisibility(View.INVISIBLE) 使我的应用程序崩溃

javascript - 无法在 Karaf OSGi 中加载 ScriptEngineManager 和 ScriptEngine(找不到 Nashorn)

java - 在Android中创建应用程序时如何只创建一次变量?

php - 在 PHP/MySQL 应用程序中保护敏感数据的实用方法?

通过 MakeSignature.signDeferred 进行外部签名时,Java iText 5 签名无效