Flutter RFC3161时间戳插件tsa_rfc3161的使用
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.txt
和 file.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
更多关于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'),
),
],
),
),
),
);
}
}
在这个示例中:
- 我们定义了一个Flutter应用,其中包含一个按钮用于获取时间戳。
tsa_rfc3161
插件被用来与指定的时间戳服务器进行通信。TsaClient.getTimeStamp
方法被调用,传入时间戳服务器的URL和需要加时间戳的数据哈希值。- 获取到的时间戳令牌或错误结果被显示在页面上。
请注意,你需要将your-tsa-server-url
替换为实际的时间戳服务器URL,并将your-data-hash
替换为你实际需要加时间戳的数据哈希值。
此外,请确保时间戳服务器是可信的,并且支持RFC 3161标准。