Node.jsで無料のタイムスタンプサービスに接続する

## タイムスタンプサービス

無料でタイムスタンプトークンを発行するサービス、[Free TSA Project](http://eswg.jnsa.org/sandbox/freetsa/) に接続します。タイムスタンプリクエスト、タイムスタンプレスポンス、タイムスタンプトークンの出力、解析には[jsrsasign](https://kjur.github.io/jsrsasign/)を使用します。

## jsrsasign のダウンロード

NPMでダウンロードします。

```
> npm install jsrsasign jsrsasign-util
```

## タイムスタンププロトコル

タイムスタンプに関わる仕様は、[RFC3161](https://datatracker.ietf.org/doc/html/rfc3161)、[RFC5816](https://datatracker.ietf.org/doc/html/rfc5816) で 定義されています。

HTTP通信で行う際の仕様が [RFC3161 の 3.4 Time-Stamp Protocol via HTTP](https://datatracker.ietf.org/doc/html/rfc3161#section-3.4) に記載されています。

## タイムスタンプサービスへの接続

今回は、[Fetch API](https://developer.mozilla.org/ja/docs/Web/API/fetch)を使用して、タイムスタンプサービスへ接続しました。

Content-Type に application/timestamp-query を指定し、ボディ句にDERエンコードした タイムスタンプリクエストを設定し、Postメソッドでタイムスタンプサービスに送ります。

## サンプルプログラム

以下は、タイムスタンプサービスに接続し、タイムスタンプレスポンス、タイムスタンプトークンを出力するサンプルプログラムです。

```javascript

const {createHash, } = require('node:crypto');
const {KJUR, ASN1HEX} = require('jsrsasign');


//ハッシュ値の生成
const hash = createHash('sha256');
hash.update('Hello World');

//MessageImprintの作成
var messageImprint = new KJUR.asn1.tsp.MessageImprint({
    alg: 'sha256',
    hash: hash.digest('hex')
});

//TimeStampReqの作成
var timestampReq = new KJUR.asn1.tsp.TimeStampReq({
    messageImprint: messageImprint,
    policy: null,
    nonce: null,
    certreq: true
});

//ファイルへ出力
const arrybuf1 = Uint8Array.from(Buffer.from(timestampReq.tohex(), "hex"));
const fs1 = require('fs');
fs1.writeFile('HelloWorld.req', arrybuf1, err => {
    if (err) throw err;
});

// FetchAPIのオプション準備
const param  = {
    method: "POST",
    headers: {
      "Content-Type": "application/timestamp-query"
    },
  
    // リクエストボディ
    body: arrybuf1
  };
  
var hexRes;
fetch("http://eswg.jnsa.org/freetsa", param)
    .then( (resposne)  => {
        return resposne.arrayBuffer();
    })
    .then((post) => {
        //タイムスタンプレスポンスを16進文字列変換
        hexRes = Buffer.from(new Uint8Array(post)).toString("hex");

        //タイムスタンプレスポンスを解析
        const parser = new KJUR.asn1.tsp.TSPParser();
        const timeStampResp = parser.getResponse(hexRes);
        //console.log(timeStampResp);

        //タイムスタンプレスポンスからタイムスタンプトークンを取り出す
        const hexToken = ASN1HEX.getTLV(hexRes, 18);
        const timeStampToken = parser.getToken(hexToken);
        //console.log(timeStampToken);

        //タイムスタンプレスポンスのファイルへの出力
        const arrybuf2 = Uint8Array.from(Buffer.from(hexRes, "hex"));
        const fs2 = require('fs');
        fs2.writeFile('HelloWorld.tsr', arrybuf2, err => {
            if (err) throw err;
        });

        //タイムスタンプレスポンスのファイルへの出力
        const arrybuf3 = Uint8Array.from(Buffer.from(hexToken, "hex"));
        const fs3 = require('fs');
        fs3.writeFile('HelloWorld.tst', arrybuf3, err => {
            if (err) throw err;
        });

        //タイムスタンプトークンを解析した内容を表示
        console.log(ASN1HEX.dump(hexToken));

    })
    .catch((error) => {
        console.error('Error:', error);
    });
```

## 実行結果

タイムスタンプトークンを解析した結果です。

```
SEQUENCE
  ObjectIdentifier signed-data (1 2 840 113549 1 7 2)
  [0]
    SEQUENCE
      INTEGER 03
      SET
        SEQUENCE
          ObjectIdentifier sha1 (1 3 14 3 2 26)
          NULL
      SEQUENCE
        ObjectIdentifier tstinfo (1 2 840 113549 1 9 16 1 4)
        [0]
          OCTETSTRING, encapsulates
            SEQUENCE
              INTEGER 01
              ObjectIdentifier anyPolicy (2 5 29 32 0)
              SEQUENCE
                SEQUENCE
                  ObjectIdentifier sha256 (2 16 840 1 101 3 4 2 1)
                  NULL
                OCTETSTRING a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
              INTEGER 081f31
              GeneralizedTime 20230127151752Z
              SEQUENCE
                INTEGER 01
                [0] 01f4
                [1] 64
              BOOLEAN TRUE
              [0]
                [4]
                  SEQUENCE
                    SET
                      SEQUENCE
                        ObjectIdentifier countryName (2 5 4 6)
                        PrintableString 'JP'
                    SET
                      SEQUENCE
                        ObjectIdentifier organizationName (2 5 4 10)
                        PrintableString 'JNSA'
                    SET
                      SEQUENCE
                        ObjectIdentifier organizationalUnitName (2 5 4 11)
                        PrintableString 'ESWG'
                    SET
                      SEQUENCE
                        ObjectIdentifier commonName (2 5 4 3)
                        PrintableString 'JNSA PKI Sandbox FreeTSA 300001'
      [0]
        SEQUENCE
          SEQUENCE
            [0]
              INTEGER 02
            INTEGER 300001
            SEQUENCE
              ObjectIdentifier SHA256withRSA (1 2 840 113549 1 1 11)
              NULL
            SEQUENCE
              SET
                SEQUENCE
                  ObjectIdentifier countryName (2 5 4 6)
                  PrintableString 'JP'
              SET
                SEQUENCE
                  ObjectIdentifier organizationName (2 5 4 10)
                  PrintableString 'JNSA'
              SET
                SEQUENCE
                  ObjectIdentifier organizationalUnitName (2 5 4 11)
                  PrintableString 'ESWG'
              SET
                SEQUENCE
                  ObjectIdentifier commonName (2 5 4 3)
                  PrintableString 'JNSA PKI Sandbox CA Root 2'
            SEQUENCE
              UTCTime 150225063024Z
              UTCTime 250222063024Z
            SEQUENCE
              SET
                SEQUENCE
                  ObjectIdentifier countryName (2 5 4 6)
                  PrintableString 'JP'
              SET
                SEQUENCE
                  ObjectIdentifier organizationName (2 5 4 10)
                  PrintableString 'JNSA'
              SET
                SEQUENCE
                  ObjectIdentifier organizationalUnitName (2 5 4 11)
                  PrintableString 'ESWG'
              SET
                SEQUENCE
                  ObjectIdentifier commonName (2 5 4 3)
                  PrintableString 'JNSA PKI Sandbox FreeTSA 300001'
            SEQUENCE
              SEQUENCE
                ObjectIdentifier rsaEncryption (1 2 840 113549 1 1 1)
                NULL
              BITSTRING, encapsulates
                SEQUENCE
                  INTEGER 00e21e0dff7080396a6b25561a781ea2..(total 257bytes)..3bbb874987f489f4010a134a662dd57b
                  INTEGER 010001
            [3]
              SEQUENCE
                SEQUENCE
                  ObjectIdentifier keyUsage (2 5 29 15)
                  OCTETSTRING, encapsulates
                    BITSTRING 06c0
                SEQUENCE
                  ObjectIdentifier extKeyUsage (2 5 29 37)
                  BOOLEAN TRUE
                  OCTETSTRING, encapsulates
                    SEQUENCE
                      ObjectIdentifier timeStamping (1 3 6 1 5 5 7 3 8)
                SEQUENCE
                  ObjectIdentifier subjectKeyIdentifier (2 5 29 14)
                  OCTETSTRING, encapsulates
                    OCTETSTRING 8b1997d03f0768ce93e79343dbed80992b9c5a09
                SEQUENCE
                  ObjectIdentifier authorityKeyIdentifier (2 5 29 35)
                  OCTETSTRING, encapsulates
                    SEQUENCE
                      [0] d24b314b551a3c5a2d868cd7ecdee83fda5fcf83
                      [1]
                        [4]
                          SEQUENCE
                            SET
                              SEQUENCE
                                ObjectIdentifier countryName (2 5 4 6)
                                PrintableString 'JP'
                            SET
                              SEQUENCE
                                ObjectIdentifier organizationName (2 5 4 10)
                                PrintableString 'JNSA'
                            SET
                              SEQUENCE
                                ObjectIdentifier organizationalUnitName (2 5 4 11)
                                PrintableString 'ESWG'
                            SET
                              SEQUENCE
                                ObjectIdentifier commonName (2 5 4 3)
                                PrintableString 'JNSA PKI Sandbox CA Root 2'
                      [2] 038d7ea4c68002
                SEQUENCE
                  ObjectIdentifier basicConstraints (2 5 29 19)
                  OCTETSTRING, encapsulates
                    SEQUENCE {}
                SEQUENCE
                  ObjectIdentifier cRLDistributionPoints (2 5 29 31)
                  OCTETSTRING, encapsulates
                    SEQUENCE
                      SEQUENCE
                        [0]
                          [0]
                            [6] http://eswg.jnsa.org/sandbox/freeca/ca2.crl
          SEQUENCE
            ObjectIdentifier SHA256withRSA (1 2 840 113549 1 1 11)
            NULL
          BITSTRING 0066cdfc825202594e8a907866ccf676..(total 257bytes)..ebca3d4512b7ef9f689db6e04f7bb760
        SEQUENCE
          SEQUENCE
            [0]
              INTEGER 02
            INTEGER 038d7ea4c68002
            SEQUENCE
              ObjectIdentifier SHA256withRSA (1 2 840 113549 1 1 11)
              NULL
            SEQUENCE
              SET
                SEQUENCE
                  ObjectIdentifier countryName (2 5 4 6)
                  PrintableString 'JP'
              SET
                SEQUENCE
                  ObjectIdentifier organizationName (2 5 4 10)
                  PrintableString 'JNSA'
              SET
                SEQUENCE
                  ObjectIdentifier organizationalUnitName (2 5 4 11)
                  PrintableString 'ESWG'
              SET
                SEQUENCE
                  ObjectIdentifier commonName (2 5 4 3)
                  PrintableString 'JNSA PKI Sandbox CA Root 2'
            SEQUENCE
              UTCTime 150225051928Z
              UTCTime 250304051928Z
            SEQUENCE
              SET
                SEQUENCE
                  ObjectIdentifier countryName (2 5 4 6)
                  PrintableString 'JP'
              SET
                SEQUENCE
                  ObjectIdentifier organizationName (2 5 4 10)
                  PrintableString 'JNSA'
              SET
                SEQUENCE
                  ObjectIdentifier organizationalUnitName (2 5 4 11)
                  PrintableString 'ESWG'
              SET
                SEQUENCE
                  ObjectIdentifier commonName (2 5 4 3)
                  PrintableString 'JNSA PKI Sandbox CA Root 2'
            SEQUENCE
              SEQUENCE
                ObjectIdentifier rsaEncryption (1 2 840 113549 1 1 1)
                NULL
              BITSTRING, encapsulates
                SEQUENCE
                  INTEGER 00ca994a1664c97ec76b061db4cc06b7..(total 257bytes)..49e9c140dbadd1ec834978be39192bed
                  INTEGER 010001
            [3]
              SEQUENCE
                SEQUENCE
                  ObjectIdentifier keyUsage (2 5 29 15)
                  OCTETSTRING, encapsulates
                    BITSTRING 0106
                SEQUENCE
                  ObjectIdentifier subjectKeyIdentifier (2 5 29 14)
                  OCTETSTRING, encapsulates
                    OCTETSTRING d24b314b551a3c5a2d868cd7ecdee83fda5fcf83
                SEQUENCE
                  ObjectIdentifier authorityKeyIdentifier (2 5 29 35)
                  OCTETSTRING, encapsulates
                    SEQUENCE
                      [0] d24b314b551a3c5a2d868cd7ecdee83fda5fcf83
                      [1]
                        [4]
                          SEQUENCE
                            SET
                              SEQUENCE
                                ObjectIdentifier countryName (2 5 4 6)
                                PrintableString 'JP'
                            SET
                              SEQUENCE
                                ObjectIdentifier organizationName (2 5 4 10)
                                PrintableString 'JNSA'
                            SET
                              SEQUENCE
                                ObjectIdentifier organizationalUnitName (2 5 4 11)
                                PrintableString 'ESWG'
                            SET
                              SEQUENCE
                                ObjectIdentifier commonName (2 5 4 3)
                                PrintableString 'JNSA PKI Sandbox CA Root 2'
                      [2] 038d7ea4c68002
                SEQUENCE
                  ObjectIdentifier basicConstraints (2 5 29 19)
                  OCTETSTRING, encapsulates
                    SEQUENCE
                      BOOLEAN TRUE
          SEQUENCE
            ObjectIdentifier SHA256withRSA (1 2 840 113549 1 1 11)
            NULL
          BITSTRING 0074d102153c95b437236c370fd38596..(total 257bytes)..85cf3e9756d009f65b7efecd82507934
      SET
        SEQUENCE
          INTEGER 01
          SEQUENCE
            SEQUENCE
              SET
                SEQUENCE
                  ObjectIdentifier countryName (2 5 4 6)
                  PrintableString 'JP'
              SET
                SEQUENCE
                  ObjectIdentifier organizationName (2 5 4 10)
                  PrintableString 'JNSA'
              SET
                SEQUENCE
                  ObjectIdentifier organizationalUnitName (2 5 4 11)
                  PrintableString 'ESWG'
              SET
                SEQUENCE
                  ObjectIdentifier commonName (2 5 4 3)
                  PrintableString 'JNSA PKI Sandbox CA Root 2'
            INTEGER 300001
          SEQUENCE
            ObjectIdentifier sha1 (1 3 14 3 2 26)
            NULL
          [0]
            SEQUENCE
              ObjectIdentifier contentType (1 2 840 113549 1 9 3)
              SET
                ObjectIdentifier tstinfo (1 2 840 113549 1 9 16 1 4)
            SEQUENCE
              ObjectIdentifier signingTime (1 2 840 113549 1 9 5)
              SET
                UTCTime 230127151752Z
            SEQUENCE
              ObjectIdentifier messageDigest (1 2 840 113549 1 9 4)
              SET
                OCTETSTRING 39dc503d7c54ee4fc7f1677abe56ea2e2a346bf1
            SEQUENCE
              ObjectIdentifier signingCertificate (1 2 840 113549 1 9 16 2 12)
              SET
                SEQUENCE
                  SEQUENCE
                    SEQUENCE
                      OCTETSTRING f4bc670eb100326199e89e59b9841fbaeb460d13
          SEQUENCE
            ObjectIdentifier rsaEncryption (1 2 840 113549 1 1 1)
            NULL
          OCTETSTRING 0575bd9760c2804633954b6700b6b91d..(total 256bytes)..0047f1b2399ee48335bca93a02c857f2
```