QSL卡片的数字签名
- 前言
近年来, 越来越多的电台不再发送纸质QSL卡片, 转而使用电子版QSL卡片或使用在线日志服务.我们意识到在线日志服务过于依赖某些中心化网站, 且不足以展示电台个性, 因而无法完全取代纸质QSL卡片.
同时, 不含有签名电子版QSL卡片极易被伪造, 不能独自有效证明通联的真实性. 本文提出了一种可行的数字签名方案, 在不影响电子QSL卡片功能、个性化QSL卡片的前提下, 对QSL卡片上的信息进行数字签名.
- 范围
本文定义了一种对数字QSL卡片进行数字签名的方法. 但本文不对公钥的分发、信任和吊销流程做出要求.
- 要求
本文提出的数字签名满足以下要求:
i. 数字签名可以被方便的识别、验证且不依赖中心化第三方服务.
ii. 数字签名不对QSL卡片设计、美观性产生显著影响
iii. 接收方对收到的QSL卡片进行格式转换等操作不影响签名有效性
iv. 接收方可以打印含有数字签名的QSL卡片, 打印后的卡片可以被独立验证.
- 规范性引用文件
GB/T 1.1-2020 标准化工作导则 第1部分:标准化文件的结构和起草规则.
本文中粗体“(不)应”、“(不)宜”、“可、不必”、“(不)能”、“(不)可能”的使用符合 《GB/T 1.1-2020 标准化工作导则 第1部分:标准化文件的结构和起草规则》中附录C的定义.
- 定义
5.1 基本定义
- 字节 由8位二进制组成的符号
- 签名有效载荷 实际被签名的数据中, 有意义的部分
- 被签名数据 数字签名算法的输入
- 签名 由文件头、签名算法描述和数字签名等部分组成的文件
5.2 SSH消息
本文多次描述SSH消息结构体, 在本文的语义下, 用到的类型有:
ssh-string
四个字节、大端序表示的字符串长度和由前述长度指定的字节串, 串中可以有Unicode NUL字符, 串位不含有多余的Unicode NUL字符.
uint32
四个字节、大端序表示的32位无符号整数.
byte[N]
N个字节, 无其它信息
varint
变长数字,其最高位表示是否为该数最后一位(1为非,0为是),如150表示为10010110 00000001
,16进制转写为96 01
. 注:此类型非SSH消息定义.
具体实现
6.1. 数字签名算法选择
在本设计中, 我们将使用SSH密钥对QSL卡片上的信息进行数字签名, 这是因为SSH的签名消息相比于PGP签名后的消息更小, 更易于在QSL卡片上展示.
对于具体的算法选择, 我们使用Ed25519椭圆曲线密码, 这是因为Ed25519的公钥大小和签名大小都足够小, 可以更方便地嵌入在QSL卡片中.
签名内容不包含被签名的信息.
6.2 数字签名有效载荷ADIF
数字签名的有效载荷为一ADIF文件, 其可以从QSL卡片上所展示的信息唯一构造.
6.2.1 构造ADIF
被数字签名的信息使用ADIF格式, 它人类可读的特性使得它可以被简单地构造, 同时由于数字签名不包含被签名的信息, 被签名信息的长度对签名的长度没有影响.
以下信息会依次包含在ADIF数据当中:
- QSO_DATE
- TIME_ON
- BAND
- CALL
- MODE
- STATION_CALLSIGN
- OPERATOR
其中, QSO_DATE
为8位数字(年、月、日)表示的协调时(UTC)日期, TIME_ON
为6位数字(时、分、秒)表示的协调时(UTC)时间, 无论QSL卡片上是否印刷出了通联的秒数, 时间都应截断至整分钟(即将秒数简单置0).
上述各项均应用大写字母.如果QSL卡片上没有指明操作员, 则OPERATOR
为不含任何修饰的STATION_CALLSIGN
.
如, 以下的QSL卡片:
TO BB0BBB DE B4/BG6TOE
Date Time (BJT) / Freq / Mode / RST
2023-01-01 02:00:59 14.245 MHz USB 59 59
[x]PSE [ ]TNX QSL
VY TU! 73
其ADIF转写为:
<QSO_DATE:8>20221231<TIME_ON:6>180000<BAND:3>20M<CALL:6>BB0BBB<MODE:3>USB<STATION_CALLSIGN:9>B4/BG6TOE<OPERATOR:6>BG6TOE<EOR>
该文件的xxd
转储为:
00000000: 3c51 534f 5f44 4154 453a 383e 3230 3232 <QSO_DATE:8>2022
00000010: 3132 3331 3c54 494d 455f 4f4e 3a36 3e31 1231<TIME_ON:6>1
00000020: 3830 3030 303c 4241 4e44 3a33 3e32 304d 80000<BAND:3>20M
00000030: 3c43 414c 4c3a 363e 4242 3042 4242 3c4d <CALL:6>BB0BBB<M
00000040: 4f44 453a 333e 5553 423c 5354 4154 494f ODE:3>USB<STATIO
00000050: 4e5f 4341 4c4c 5349 474e 3a39 3e42 342f N_CALLSIGN:9>B4/
00000060: 4247 3654 4f45 3c4f 5045 5241 544f 523a BG6TOE<OPERATOR:
00000070: 363e 4247 3654 4f45 3c45 4f52 3e 6>BG6TOE<EOR>
需要注意:文末不应有任何多余字符(含换行、空格、制表符等), 即<EOR>
后不含有任何字符.
6.2.2 构造含有多个QSO的ADIF信息
若一张QSL卡片上含有多个QSO, 则对应的ADIF文件应按照通联的时间顺序, 直接拼接各个QSO的ADIF数据,文末不应有任何多余字符(含换行、空格、制表符等), 即, 以最后一个QSO的<EOR>
后不含有任何字符.
6.3 签名数据
6.3.1 展示方式
签名数据可以在经由Base64编码后直接显示在QSL卡片上. 以文本形式表示的签名数据宜使用等宽字体排版. 使用的字体应足以分辨i
、l
、1
, O
、o
、0
, 5
、S
等Base64使用的编码字符.
签名数据可以在经由Base32编码后直接显示在QSL卡片上. 以文本形式表示的签名数据宜使用等宽字体排版.
签名数据宜在经由Base45编码后包含于QR Code中. 此时签名数据应为独立的二维码. 该二维码可使用除黑、白之外的颜色, 但应用浅色区域作为二维码背景、深色作为二维码前景色.
为保证生成二维码识别成功率, 使用QR Code为载体的签名数据不宜使用Base45以外的编码.
6.3.2 二进制签名数据格式
二进制签名为SSH签名结构体, 其格式为:
byte[6] MAGIC_PREAMBLE
uint32 SIG_VERSION
ssh-string publickey
ssh-string namespace
ssh-string reserved
ssh-string hash_algorithm
ssh-string signature
其中:MAGIC_PREAMBLE
为SSHSIG
, SIG_VERSION
为1.
publickey
为序列化后的签名密钥的公钥.
namespace
应为adif-qslv1
.
reserved
应为空.
hash_algorithm
应为sha512
(即, 总是使用SHA512对数据进行签名).
signature
为SSH正文的签名, 使用ssh-ed25519
算法.
6.3.3 签名的精简
为了使得签名内容更容易被展示,可以对签名内容进行精简。精简之后的签名仅包含头部及ED25519签名数据。其中,头部固定为DQSLV1
,后紧跟64字节的ED25519签名X||Y
。当接收方获得开头为DQSLV1
的签名数据时,应将其展开为标准签名格式进行校验。
6.3.4 被签名内容
实际被签名的内容为:
byte[6] MAGIC_PREAMBLE
ssh-string namespace
ssh-string reserved
ssh-string hash_algorithm
ssh-string H(message)
其中:MAGIC_PREAMBLE
为SSHSIG
, SIG_VERSION
为1.
publickey
应为序列化后的签名密钥的公钥.namespace
应为adif-qslv1
.
reserved
应为空.
hash_algorithm
应为sha512
(即, 总是使用SHA512对数据进行签名).
message
4.2 节所描述的ADIF文件, H(message)
为其SHA-512算法下的指纹.
将此内容经由SSH Message格式编码后, 使用Ed25519私钥和ssh-ed25519
进行签名,即得到4.3.1节中的signature
字段.
- 附加原始QSO数据
签名前可附加原始QSO数据,以方便机器直接识别、校验。原始QSO数据为精简表示的极小QSO元数据,包含以下字段:通联时间、通联波段、通联模式、收方呼号、发方呼号、OP。
其格式为:
byte[6] MAGIC_PREAMBLE
varint call
varint station_callsign
varint operator
ssh-string data
其中,call、station_callsign、operator为呼号的37进制数表示(见下表):
+---------++----+----++----+----+
|Char|Num ||Char|Num ||Char|Num |
+---------++----+----++----+----+
| 0 | 0 || C | 12 || O | 24 |
| 1 | 1 || D | 13 || P | 25 |
| 2 | 2 || E | 14 || Q | 26 |
| 3 | 3 || F | 15 || R | 27 |
| 4 | 4 || G | 16 || S | 28 |
| 5 | 5 || H | 17 || T | 29 |
| 6 | 6 || I | 18 || U | 30 |
| 7 | 7 || J | 19 || V | 31 |
| 8 | 8 || K | 20 || W | 32 |
| 9 | 9 || L | 21 || X | 33 |
| A | 10 || M | 22 || Y | 34 |
| B | 11 || N | 23 || Z | 35 |
| / | 36 |+----+----++----+----+
+----+----+
如B1CRA
表示为11 * 37^4 + 1 * 37^3 + 12 * 37^2 + 27 * 37 + 10 = 20683861
其中,data为多个最小QSO拼接而成的字符串,其格式为
varint QSO Timestamp
varint Band
byte[8] Mode
其中QSO Timestamp为协调时1970年元旦以来的秒数(但精确到分钟)。Band为波段对应频率的低端(千赫兹)数,如20米波段表示为14000。Mode为表示模式的字符串,不足8字节用\0
补全。
- 示例
假设 ST4TION
使用电台 C3SHI
与 TE5T
在北京时2023年1月1日10:05:30,在20米段上使用MFSK调制方式完成了一次通联完成了一次通联. 现ST4TION
欲以其自己名义签名如下QSL卡片:
TO TE5T DE C3SHI OP ST4TION
Date Time (BJT) / Freq / Mode / RST
2023-01-01 10:00 14.074 MHz MFSK 59 59
[x]PSE [ ]TNX QSL
VY TU! 73
ST4TION
的私钥为:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACADTnJZ6blw4CsqVoxzv9iWVVl0ycM8Neqb9QvTyvKqCAAAAJiuWf0orln9
KAAAAAtzc2gtZWQyNTUxOQAAACADTnJZ6blw4CsqVoxzv9iWVVl0ycM8Neqb9QvTyvKqCA
AAAEDgyhqzLTK6rmVqjfvHpvHPYJzdeVuDhRo93XO98jDl1QNOclnpuXDgKypWjHO/2JZV
WXTJwzw16pv1C9PK8qoIAAAAFW1hdHN1QEJHNlRPRS1Ob3RlYm9vaw==
-----END OPENSSH PRIVATE KEY-----
其公钥为:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIANOclnpuXDgKypWjHO/2JZVWXTJwzw16pv1C9PK8qoI
则其构造如下的ADIF数据(签名有效载荷):
<QSO_DATE:8>20230101<TIME_ON:6>020500<BAND:3>20M<CALL:4>TE5T<MODE:4>MFSK<STATION_CALLSIGN:5>C3SHI<OPERATOR:7>ST4TION<EOR>
需要注意:
- 卡面上的北京时间应转换为协调世界时
- 生成的ADIF文件中的秒被无条件截断至0
- 波段从14.074得出, 为20M
- RST不包含在ADIF当中
该ADIF的SHA512
指纹为:
5d10 5c01 843a 14ad 9852 5f40 f9e9 36d5
0e00 56b0 d98b a04f 6d1d d337 efb8 11bb
f397 52d3 6233 6b64 ab8f 430f cf6b e95d
bfb4 39b9 26c8 fb39 9cbf 414a b386 a1b4
构造如下被签名数据:
00000000: 5353 4853 4947 0000 000a 6164 6966 2d71 SSHSIG....adif-q
00000010: 736c 7631 0000 0000 0000 0006 7368 6135 slv1........sha5
00000020: 3132 0000 0040 5d10 5c01 843a 14ad 9852 12...@].\..:...R
00000030: 5f40 f9e9 36d5 0e00 56b0 d98b a04f 6d1d _@..6...V....Om.
00000040: d337 efb8 11bb f397 52d3 6233 6b64 ab8f .7......R.b3kd..
00000050: 430f cf6b e95d bfb4 39b9 26c8 fb39 9cbf C..k.]..9.&..9..
00000060: 414a b386 a1b4 AJ....
应用前述私钥及ssh-ed25519
签名方式进行签名:
00000000: 0000 0053 0000 000b 7373 682d 6564 3235 ...S....ssh-ed25
00000010: 3531 3900 0000 4082 84f9 edcb 8ef8 6cdf 519...@.......l.
00000020: 5bee c347 6762 84ea ce4b 4644 6429 6900 [..Ggb...KFDd)i.
00000030: 4139 6e79 9bbd f74c 2b94 0e53 541e 4dfa A9ny...L+..ST.M.
00000040: 94db 704a 9b77 aad1 4dcd 2e5d 6b3f 30c6 ..pJ.w..M..]k?0.
00000050: 44c6 7e84 ca4d 07 D.~..M.
构造签名:
00000000: 5353 4853 4947 0000 0001 0000 0033 0000 SSHSIG.......3..
00000010: 000b 7373 682d 6564 3235 3531 3900 0000 ..ssh-ed25519...
00000020: 2003 4e72 59e9 b970 e02b 2a56 8c73 bfd8 .NrY..p.+*V.s..
00000030: 9655 5974 c9c3 3c35 ea9b f50b d3ca f2aa .UYt..<5........
00000040: 0800 0000 0a61 6469 662d 7173 6c76 3100 .....adif-qslv1.
00000050: 0000 0000 0000 0673 6861 3531 3200 0000 .......sha512...
00000060: 5300 0000 0b73 7368 2d65 6432 3535 3139 S....ssh-ed25519
00000070: 0000 0040 8284 f9ed cb8e f86c df5b eec3 ...@.......l.[..
00000080: 4767 6284 eace 4b46 4464 2969 0041 396e Ggb...KFDd)i.A9n
00000090: 799b bdf7 4c2b 940e 5354 1e4d fa94 db70 y...L+..ST.M...p
000000a0: 4a9b 77aa d14d cd2e 5d6b 3f30 c644 c67e J.w..M..]k?0.D.~
000000b0: 84ca 4d07 ..M.
精简签名:
00000000: 4451 534c 5631 8284 f9ed cb8e f86c df5b DQSLV1.......l.[
00000010: eec3 4767 6284 eace 4b46 4464 2969 0041 ..Ggb...KFDd)i.A
00000020: 396e 799b bdf7 4c2b 940e 5354 1e4d fa94 9ny...L+..ST.M..
00000030: db70 4a9b 77aa d14d cd2e 5d6b 3f30 c644 .pJ.w..M..]k?0.D
00000040: c67e 84ca 4d07 .~..M.
签名的Base64编码:
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgA05yWem5cOArKlaMc7/YllVZdMnDPDXq
m/UL08ryqggAAAAKYWRpZi1xc2x2MQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUxOQAA
AECChPnty474bN9b7sNHZ2KE6s5LRkRkKWkAQTlueZu990wrlA5TVB5N+pTbcEqbd6rRTc0uXWs/
MMZExn6Eyk0H
精简签名的Base64编码:
RFFTTFYxgoT57cuO+GzfW+7DR2dihOrOS0ZEZClpAEE5bnmbvfdMK5QOU1QeTfqU23BKm3eq0U3N
Ll1rPzDGRMZ+hMpNBw==
签名的Base45编码:
1OAK69*B9000100000610000B00ZQET7D CSF6RW6C97000524C-9MGB.JNCFS%F50YHHBOA0J+DB MPNR7TTT1:U%YQMUUN010002E1AVCC-CIFE1WDY86000000000V 0 8DRW6KE60008MA0006K1OQEBX50UCVW61A6000J10MMG QV0XPBIVTASD8U919KKCZUTAN93T8QA5K10WB7 GFV0OES9CWI2OAH$3NUVGXRJJ9Y5FVKQB.PK BL:7-2P94PJZG9X9
精简签名的Base45编码:
TS8*NAF+AMMG QV0XPBIVTASD8U919KKCZUTAN93T8QA5K10WB7 GFV0OES9CWI2OAH$3NUVGXRJJ9Y5FVKQB.PK BL:7-2P94PJZG9X9
- 信息性引用文件
RFC4634 US Secure Hash Algorithms (SHA and HMAC-SHA)
RFC4648 The Base16, Base32, and Base64 Data Encodings
RFC8709 Ed25519 and Ed448 Public Key Algorithms for the Secure Shell (SSH) Protocol
RFC9285 The Base45 Data Encoding)
ADIF Amateur Data Interchange Format (ADIF) Specification