Flutter RFC3161时间戳插件tsa_rfc3161的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter RFC3161时间戳插件tsa_rfc3161的使用

Flutter TSA (时间戳认证机构) 客户端 rfc3161

此解决方案基于 RFC3161,以证明文件未在您使用该库的时间点之后创建或更新。

RFC3161 没有使用 OpenSSL!

在 macOS 和 Android 配置下测试过,使用了 Digicert 和 Certigna TSA。 (如果 TSA 主机不提供 CORS 头,则在 Flutter Web 上会失败)

import 'package:dio/dio.dart';
import 'package:tsa_rfc3161/tsa_rfc3161.dart';

// ...

TSARequest tsq = TSARequest.fromFile(
    filepath: filepath,
    algorithm: TSAHashAlgo.sha256,
    nonce: nonceValue,
    certReq: true);

TSAResponse tsr = tsq.run(hostname: "http://timestamp.digicert.com");

tsr.write("file.digicert.tsr"); // 保存时间戳

TimeStampQuery : tsq

如果您想保存 TimeStampQuery,可以:

tsq.write("file.digicert.tsq");

此文件 file.digicert.tsq 与通过以下 OpenSSL 命令生成的文件相同:

openssl ts -query -data file.txt -no_nonce -sha512 -cert -out file.digicert.tsq

TimeStampResponse : tsr 是您应该保存/共享的

TimeStampResponse 可以作为证据保存或共享。

file.digicert.tsr 与由 Digicert 的 HTTP 服务器生成的文件相同:

curl -H 'Content-Type: application/timestamp-query' --data-binary '@file.digicert.tsq'  http://timestamp.digicert.com > file.digicert.tsr

file.digicert.tsr 可以使用以下 OpenSSL CLI 命令读取:

$ openssl ts -reply -in file.digicert.tsr -text 

Version: 1
Policy OID: 2.16.840.1.114412.7.1
Hash Algorithm: sha512
Message data:
    0000 - 89 bd 94 b7 92 4b 2f 16-d8 c5 c0 0f 11 02 12 b1   .....K/.........
    0010 - bb b1 5a bb 72 7d be 06-33 bf 7d d0 9f 6f d6 07   ..Z.r}..3.}..o..
    0020 - 02 4d a3 df d6 7b cf c7-89 e2 2f 2d d9 fa 9b c3   .M...{..../-....
    0030 - 39 9a d4 34 11 e1 11 d8-c6 7b a7 a0 b4 96 42 2d   9..4.....{....B-
Serial number: 0x4194EF54150D2496B2C3F1A78D82C41B
Time stamp: Sep  7 08:37:47 2024 GMT
Accuracy: unspecified
Ordering: no
Nonce: 0x0191CBA1D914
TSA: unspecified
Extensions:

任何人都可以检查 Digicert 提供的时间戳响应 tsr

由于 file.digicert.tsr 包含

"Time stamp: Sep  7 08:37:47 2024 GMT"

除了您的文件外,您可以共享文件 file.tsr,以便任何需要的人都能确信 file.txt 在 “Sep 7 08:37:47 2024 GMT” 之后未被创建或修改。

例如: 任何人拥有 file.txtfile.txt.tsr 都可以验证由 Digicert 提供的时间戳。

# 下载来自 Digicert 服务器的证书
wget https://cacerts.digicert.com/DigiCertAssuredIDRootCA.crt.pem

# 验证时间戳证明是否有效
openssl ts -verify -data file.txt -in file.txt.tsr -CAfile DigiCertAssuredIDRootCA.crt.pem

Verification: OK

如果需要身份验证

身份验证可用:

Response response = await tsq.run(
      hostname: "https://timestamp.dhimyotis.com/api/v1/",
      credentials: "$user:$password");

哈希算法

哈希算法:SHA1, SHA256, SHA384, SHA512

解析 TimeStampResponse tsq

TSAResponse 类提供了尝试。ASN.1 数据非常难以解析。然而,您可以将 HTTP 响应解析为一个 ASN1Sequence 并像这样展示数据:

TSAResponse tsr = TSAResponse.fromHTTPResponse(response: response);
String result = explore(tsr.asnsequence, 0);

result 包含重要数据,如
"2024-09-10 12:53:47.000Z" 作为时间戳
"0x5519275DFC193E5D3B11154FF6F2E8EB" 作为序列号
"1725972827265" 作为非号码值

详细信息 :

ASN1Sequence
    ASN1Sequence
        ASN1Integer : 0 : 0x00 
    ASN1Sequence
        ASN1ObjectIdentifier : 1.2.840.113549.1.7.2 - signedData
        ASN1Sequence
            ASN1Integer : 3 : 0x03 
            ASN1Set
                ASN1Sequence
                    ASN1ObjectIdentifier : 2.16.840.1.101.3.4.2.1 - sha256
                    ASN1Null
            ASN1Sequence
                ASN1ObjectIdentifier : 1.2.840.113549.1.9.16.1.4 - id-ct-TSTInfo
                ASN1Sequence
                    ASN1Integer : 1 : 0x01 
                    ASN1ObjectIdentifier : 2.16.840.1.114412.7.1 - time-stamping
                    ASN1Sequence
                        ASN1Sequence
                            ASN1ObjectIdentifier : 2.16.840.1.101.3.4.2.1 - sha256
                            ASN1Null
                        ASN1OctetString  : length 34 '[0x4, 0x20, 0x67, 0xc5, 0x7f, 0x0, 0x4e, 0x78, 0x ...
                    ASN1Integer : 113114985523395616256261459051482900715 : 0x5519275DFC193E5D3B11154FF6F2E8EB 
                    ASN1GeneralizedTime : 2024-09-10 12:53:47.000Z
                    ASN1Integer : 1725972827265 : 0x0191DBFF4C81 
            ASN1Sequence
                ASN1Sequence
                    ASN1Sequence
                        ASN1Object : length 5 ''
                        ASN1Integer : 7002784885422699301467740558332354838} : 0x0544AFF3949D0839A6BFDB3F5FE56116 }
                        ASN1Sequence
                            ASN1ObjectIdentifier : 1.2.840.113549.1.1.11 - sha256WithRSAEncryption
                            ASN1Null
                        ASN1Sequence
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.6 - countryName
                                    ASN1PrintableString : US
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.10 - organizationName
                                    ASN1PrintableString : DigiCert, Inc.
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.3 - commonName
                                    ASN1PrintableString : DigiCert Trusted G4 RSA4096 SHA256 TimeStamping CA
                        ASN1Sequence
                            ASN1UtcTime : 2023-07-14 00:00:00.000Z
                            ASN1UtcTime : 2034-10-13 23:59:59.000Z
                        ASN1Sequence
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.6 - countryName
                                    ASN1PrintableString : US
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.10 - organizationName
                                    ASN1PrintableString : DigiCert, Inc.
                            ASN1Set
                                ASN1Sequence
                                    ASN1ObjectIdentifier : 2.5.4.3 - commonName
                                    ASN1PrintableString : DigiCert Timestamp 2023
                        ASN1Sequence
                            ASN1Sequence
                                ASN1ObjectIdentifier : 1.2.840.113549.1.1.1 - rsaEncryption
                                ASN1Null
                            ASN1BitString : [48, 130, 2, 10, 2, 130, 2, 1, 0, 163, 83, 69, 135, 29, 131, 142, 91, 172, 62, 84, 179, 35, 224, 207, 159, 215, 229, 210, 231, 93, 161, 14, 9, 220, 47, 72, 163, 151, 122, 59, 42, 156, 103, 220, 98, 21, 88, 193, 169, 147, 17, 167, 205, 170, 178, 106, 221, 16, 41, 138, 30, 98, 99, 105, 211, 88, 156, 53, 113, 191, 58, 151, 235, 148, 80, 143, 28, 32, 234, 199, 154, 59, 47, 150, 102, 227, 105, 231, 105, 254, 91, 195, 214, 43, 32, 28, 193, 151, 148, 180, 165, 80, 129, 242, 207, 203, 7, 166, 48, 104, 202, 131, 66, 218, 252, 127, 9, 36, 148, 164, 130, 26, 218, 106, 186, 216, 59, 202, 93, 222, 25, 24, 133, 251, 69, 234, 13, 97, 108, 157, 254, 113, 94, 196, 6, 154, 60, 240, 197, 46, 121, 15, 27, 102, 82, 227, 200, 214, 62, 95, 218, 67, 211, 132, 245, 208, 199, 246, 72, 45, 94, 69, 117, 150, 117, 254, 221, 16, 161, 27, 131, 193, 184, 230, 82, 149, 181, 71, 215, 120, 41, 57, 107, 224, 120, 89, 151, 227, 68, 43, 74, 213, 149, 206, 239, 8, 23, 234, 130, 100, 77, 255, 35, 227, 202, 134, 238, 180, 164, 33, 100, 112, 235, 213, 229, 160, 218, 99, 179, 46, 233, 5, 238, 170, 246, 36, 245, 29, 188, 155, 28, 178, 183, 95, 223, 240, 238, 118, 125, 49, 153, 101, 71, 85, 157, 74, 36, 47, 172, 43, 151, 190, 159, 228, 253, 123, 115, 62, 50, 238, 82, 52, 251, 212, 187, 235, 212, 160, 44, 52, 155, 227, 222, 110, 100, 25, 7, 55, 1, 145, 15, 28, 181, 81, 205, 170, 76, 102, 131, 136, 104, 98, 187, 188, 65, 27, 120, 25, 109, 228, 217, 15, 224, 88, 65, 251, 216, 177, 44, 225, 81, 175, 180, 173, 21, 6, 20, 234, 98, 8, 19, 211, 105, 30, 124, 100, 77, 157, 15, 223, 206, 209, 94, 140, 170, 171, 80, 21, 201, 179, 202, 188, 215, 196, 59, 104, 68, 163, 165, 59, 66, 253, 115, 125, 238, 221, 10, 255, 121, 52, 16, 126, 166, 92, 10, 88, 76, 0, 62, 133, 105, 117, 199, 131, 100, 214, 117, 205, 143, 18, 118, 86, 165, 36, 250, 215, 196, 107, 33, 186, 232, 31, 52, 152, 47, 58, 234, 107, 1, 176, 247, 251, 42, 134, 236, 123, 82, 56, 169, 152, 9, 161, 113, 178, 108, 113, 175, 62, 184, 111, 150, 213, 225, 16, 19, 254, 97, 71, 10, 140, 254, 240, 182, 199, 213, 199, 222, 108, 36, 240, 191, 66, 130, 202, 160, 113, 61, 156, 146, 147, 4, 180, 105, 112, 39, 13, 79, 183, 181, 54, 209, 201, 95, 8, 164, 112, 163, 236, 10, 241, 17, 46, 100, 224, 203, 34, 43, 202, 241, 40, 19, 33, 73, 81, 126, 6, 102, 211, 59, 190, 250, 235, 145, 56, 216, 81, 7, 202, 148, 183, 226, 80, 161, 243, 58, 211, 138, 131, 203, 64, 123, 2, 3, 1, 0, 1]
                        ASN1Sequence
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.15 - keyUsage
                                ASN1Boolean : true
                                ASN1OctetString  : length 6 '[0x4, 0x4, 0x3, 0x2, 0x7, 0x80]'
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.19 - basicConstraints
                                ASN1Boolean : true
                                ASN1OctetString  : length 4 '[0x4, 0x2, 0x30, 0x0]'
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.37 - extKeyUsage
                                ASN1Boolean : true
                                ASN1OctetString  : length 14 '[0x4, 0xc, 0x30, 0xa, 0x6, 0x8, 0x2b, 0x6, 0x1, 0x5, 0x5, 0x7, 0x3, 0x8]'
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.32 - certificatePolicies
                                ASN1OctetString  : length 27 '[0x4, 0x19, 0x30, 0x17, 0x30, 0x8, 0x6, 0x6, 0x67 ...
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.35 - authorityKeyIdentifier
                                ASN1OctetString  : length 26 '[0x4, 0x18, 0x30, 0x16, 0x80, 0x14, 0xba, 0x16, 0 ...
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.14 - subjectKeyIdentifier
                                ASN1OctetString  : length 24 '[0x4, 0x16, 0x4, 0x14, 0xa5, 0xb6, 0xef, 0x13, 0 ...
                            ASN1Sequence
                                ASN1ObjectIdentifier : 2.5.29.31 - cRLDistributionPoints
                                ASN1OctetString  : length 85 '[0x4, 0x53, 0x30, 0x51, 0x30, 0x4f, 0xa0, 0x4d, 0 ...
                            ASN1Sequence
                                ASN1ObjectIdentifier : 1.3.6.1.5.5.7.1.1 - authorityInfoAccess
                                ASN1OctetString  : length 134 '[0x4, 0x81, 0x83, 0x30, 0x81, 0x80, 0x30, 0x24, 0 ...
                    ASN1Sequence
                        ASN1ObjectIdentifier : 1.2.840.113549.1.1.11 - sha256WithRSAEncryption
                        ASN1Null
                    ASN1BitString : [129, 26, 214, 222, 160, 169, 181, 152, 23, 188, 112, 141, 79, 138, 60, 104, 156, 216, 37, 255, 203, 44, 228, 205, 234, 93, 34, 146, 236, 140, 34, 2, 169, 184, 207, 128, 168, 217, 231, 227, 197, 237, 38, 130, 138, 113, 47, 24, 221, 78, 182, 222, 108, 215, 225, 96, 156, 43, 237, 237, 61, 72, 142, 184, 107, 186, 124, 93, 189, 194, 97, 55, 104, 73, 119, 163, 235, 144, 170, 18, 215, 39, 133, 243, 142, 30, 146, 218, 194, 64, 56, 159, 93, 200, 160, 46, 37, 120, 37, 157, 42, 5, 122, 132, 41, 152, 182, 87, 121, 143, 219, 38, 86, 43, 176, 243, 167, 189, 55, 12, 216, 152, 118, 79, 86, 185, 82, 194, 182, 157, 56, 169, 129, 231, 109, 65, 92, 140, 105, 209, 185, 43, 196, 198, 123, 207, 156, 250, 120, 226, 147, 26, 118, 162, 105, 117, 211, 80, 228, 68, 18, 190, 32, 13, 158, 169, 68, 208, 248, 229, 73, 119, 8, 90, 33, 197, 180, 207, 152, 149, 26, 84, 186, 185, 188, 193, 105, 25, 186, 207, 22, 242, 131, 55, 52, 110, 176, 65, 38, 221, 222, 90, 151, 79, 51, 141, 212, 141, 119, 125, 117, 69, 161, 165, 88, 38, 106, 3, 69, 222, 217, 80, 181, 80, 140, 175, 86, 189, 76, 197, 225, 70, 197, 40, 211, 173, 231, 67, 0, 112, 222, 204, 152, 158, 25, 137, 3, 234, 212, 145, 55, 239, 77, 82, 243, 201, 96, 33, 196, 86, 71, 237, 218, 17, 75, 140, 50, 195, 136, 230, 88, 226, 182, 219, 62, 249, 95, 176, 66, 214, 143, 227, 23, 145, 209, 170, 192, 85, 227, 134, 191, 172, 39, 44, 65, 208, 154, 51, 74, 168, 54, 212, 185, 114, 150, 126, 151, 121, 56, 72, 95, 202, 194, 220, 61, 50, 223, 117, 214, 54, 103, 90, 137, 248, 246, 167, 199, 229, 79, 53, 60, 0, 189, 190, 156, 42, 108, 121, 1, 220, 218, 68, 230, 58, 222, 56, 59, 7, 94, 57, 88, 244, 124, 115, 49, 85, 160, 128, 17, 203, 20, 12, 126, 174, 188, 254, 164, 235, 121, 101, 170, 104, 214, 34, 202, 59, 235, 154, 130, 53, 87, 40, 22, 203, 105, 242, 50, 154, 178, 210, 216, 58, 184, 177, 70, 134, 107, 186, 23, 253, 196, 119, 108, 21, 108, 174, 171, 175, 115, 58, 232, 73, 70, 183, 213, 127, 204, 182, 56, 192, 216, 236, 28, 245, 182, 161, 184, 67, 44, 223, 78, 76, 125, 30, 104, 112, 192, 119, 10, 212, 2, 224, 92, 96, 187, 40, 255, 56, 229, 82, 90, 214, 172, 23, 34, 35, 78, 244, 236, 211, 23, 251, 80, 107, 255, 7, 119, 31, 113, 151, 68, 65, 201, 184, 70, 211, 108, 50, 124, 88, 47, 103, 71, 101, 229, 27, 115, 182, 153, 249, 107, 44, 6, 70, 239, 65, 30, 240, 240, 95, 224, 219, 217, 173, 144, 128, 68, 175, 128, 16, 65, 138]

示例代码

以下是完整的示例代码,展示了如何使用 Flutter 插件 tsa_rfc3161 来获取时间戳并将其与原始文件一起分享。


更多关于Flutter RFC3161时间戳插件tsa_rfc3161的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter RFC3161时间戳插件tsa_rfc3161的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用tsa_rfc3161插件来获取RFC 3161时间戳的示例代码。这个插件允许你从指定的时间戳服务器获取时间戳,并将其应用于你的数据。

首先,确保你已经在pubspec.yaml文件中添加了tsa_rfc3161依赖:

dependencies:
  flutter:
    sdk: flutter
  tsa_rfc3161: ^latest_version  # 替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,你可以使用以下代码来获取RFC 3161时间戳:

import 'package:flutter/material.dart';
import 'package:tsa_rfc3161/tsa_rfc3161.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String? timeStampResult;
  String? errorResult;

  void _getTimeStamp() async {
    try {
      // 替换为你的时间戳服务器URL
      String tsaUrl = "http://your-tsa-server-url";
      // 替换为你需要加时间戳的数据(通常是哈希值)
      String dataHash = "your-data-hash";

      // 获取时间戳
      TsaResult result = await TsaClient.getTimeStamp(tsaUrl, dataHash);

      // 更新状态以显示结果
      setState(() {
        timeStampResult = result.token; // 时间戳令牌
        errorResult = null;
      });
    } catch (e) {
      // 更新状态以显示错误
      setState(() {
        timeStampResult = null;
        errorResult = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('RFC 3161 Time Stamp Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              Text(
                'RFC 3161 Time Stamp Result:',
                style: TextStyle(fontSize: 20),
              ),
              if (timeStampResult != null)
                Text(
                  'Time Stamp Token:\n$timeStampResult',
                  style: TextStyle(fontSize: 16),
                ),
              if (errorResult != null)
                Text(
                  'Error:\n$errorResult',
                  style: TextStyle(color: Colors.red, fontSize: 16),
                ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _getTimeStamp,
                child: Text('Get Time Stamp'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们定义了一个Flutter应用,其中包含一个按钮用于获取时间戳。
  2. tsa_rfc3161插件被用来与指定的时间戳服务器进行通信。
  3. TsaClient.getTimeStamp方法被调用,传入时间戳服务器的URL和需要加时间戳的数据哈希值。
  4. 获取到的时间戳令牌或错误结果被显示在页面上。

请注意,你需要将your-tsa-server-url替换为实际的时间戳服务器URL,并将your-data-hash替换为你实际需要加时间戳的数据哈希值。

此外,请确保时间戳服务器是可信的,并且支持RFC 3161标准。

回到顶部