为什么 DH 素数和它的十六进制在 openssl 中不同?
Why is DH prime and its hex different in openssl?
从下面看,为什么素数和xxd hex不一样?
我正在尝试生成自己的参数,但不确定这些值的数学运算是什么...
[root@localhost]# openssl dh -in dhp.pem -text
DH Parameters: (1024 bit)
prime:
00:94:b4:12:21:6d:42:b9:e3:1a:15:de:0a:ee:b6:
4b:41:fa:8f:de:44:1e:ea:a2:a2:9c:b2:28:47:19:
88:f8:65:0a:e6:09:58:c3:69:69:b4:d5:d4:d2:b5:
21:4d:1f:9b:a9:78:58:37:94:0f:6e:51:00:62:e5:
d2:44:53:36:72:99:1f:22:fc:a3:93:ab:3a:e8:3f:
7b:1b:49:36:82:1c:c3:35:4b:ef:43:f9:d4:1d:6c:
ee:8b:8d:d1:a5:8f:55:3f:db:68:c1:2f:c2:3f:9b:
31:f9:7c:01:5f:55:19:b4:3d:58:ff:32:a3:de:a7:
62:cd:ea:28:c8:63:32:53:23
generator: 2 (0x2)
-----BEGIN DH PARAMETERS-----
MIGHAoGBAJS0EiFtQrnjGhXeCu62S0H6j95EHuqiopyyKEcZiPhlCuYJWMNpabTV
1NK1IU0fm6l4WDeUD25RAGLl0kRTNnKZHyL8o5OrOug/extJNoIcwzVL70P51B1s
7ouN0aWPVT/baMEvwj+bMfl8AV9VGbQ9WP8yo96nYs3qKMhjMlMjAgEC
-----END DH PARAMETERS-----
[root@localhost]# xxd dhp.pem
0000000: 2d2d 2d2d 2d42 4547 494e 2044 4820 5041 -----BEGIN DH PA
0000010: 5241 4d45 5445 5253 2d2d 2d2d 2d0a 4d49 RAMETERS-----.MI
0000020: 4748 416f 4742 414a 5330 4569 4674 5172 GHAoGBAJS0EiFtQr
0000030: 6e6a 4768 5865 4375 3632 5330 4836 6a39 njGhXeCu62S0H6j9
0000040: 3545 4875 7169 6f70 7979 4b45 635a 6950 5EHuqiopyyKEcZiP
0000050: 686c 4375 594a 574d 4e70 6162 5456 0a31 hlCuYJWMNpabTV.1
0000060: 4e4b 3149 5530 666d 366c 3457 4465 5544 NK1IU0fm6l4WDeUD
0000070: 3235 5241 474c 6c30 6b52 544e 6e4b 5a48 25RAGLl0kRTNnKZH
0000080: 794c 386f 354f 724f 7567 2f65 7874 4a4e yL8o5OrOug/extJN
0000090: 6f49 6377 7a56 4c37 3050 3531 4231 730a oIcwzVL70P51B1s.
00000a0: 376f 754e 3061 5750 5654 2f62 614d 4576 7ouN0aWPVT/baMEv
00000b0: 776a 2b62 4d66 6c38 4156 3956 4762 5139 wj+bMfl8AV9VGbQ9
00000c0: 5750 3879 6f39 366e 5973 3371 4b4d 686a WP8yo96nYs3qKMhj
00000d0: 4d6c 4d6a 4167 4543 0a2d 2d2d 2d2d 454e MlMjAgEC.-----EN
00000e0: 4420 4448 2050 4152 414d 4554 4552 532d D DH PARAMETERS-
00000f0: 2d2d 2d2d 0a ----.
这 2 个命令的输出完全不相关。 openssl
命令打印 pem 文件中包含的信息,xxd
命令打印文件的原始十六进制转储。
该文件包含素数,但采用名为 Privacy Enhanced Mail format, or PEM
for short. It's a human readable base64 encoded format of a binary blob which contains any piece of information packed according to ASN.1 的编码格式。
如果您尝试解析 pem 文件,即根据 ASN.1 结构解码二进制文件,您将看到以下内容:
$ openssl asn1parse -in dh.pem -inform PEM -i
0:d=0 hl=3 l= 135 cons: SEQUENCE
3:d=1 hl=3 l= 129 prim: INTEGER :94B412216D42B9E31A15DE0AEEB64B41FA8FDE441EEAA2A29CB228471988F8650AE60958C36969B4D5D4D2B5214D1F9BA9785837940F6E510062E5D244533672991F22FCA393AB3AE83F7B1B4936821CC3354BEF43F9D41D6CEE8B8DD1A58F553FDB68C12FC23F9B31F97C015F5519B43D58FF32A3DEA762CDEA28C863325323
135:d=1 hl=2 l= 1 prim: INTEGER :02
这是实际打包到二进制文件中的内容。 openssl dh
命令只是将数据解释为更易读的详细形式。目前,我无法找到表示打包 DH 参数结构的实际结构。
要真正在 xxd 输出中看到素数,需要做更多的工作,但这不是很困难。
$ cat << EOF | base64 -d | xxd
> MIGHAoGBAJS0EiFtQrnjGhXeCu62S0H6j95EHuqiopyyKEcZiPhlCuYJWMNpabTV
> 1NK1IU0fm6l4WDeUD25RAGLl0kRTNnKZHyL8o5OrOug/extJNoIcwzVL70P51B1s
> 7ouN0aWPVT/baMEvwj+bMfl8AV9VGbQ9WP8yo96nYs3qKMhjMlMjAgEC
> EOF
00000000: 3081 8702 8181 0094 b412 216d 42b9 e31a 0.........!mB...
00000010: 15de 0aee b64b 41fa 8fde 441e eaa2 a29c .....KA...D.....
00000020: b228 4719 88f8 650a e609 58c3 6969 b4d5 .(G...e...X.ii..
00000030: d4d2 b521 4d1f 9ba9 7858 3794 0f6e 5100 ...!M...xX7..nQ.
00000040: 62e5 d244 5336 7299 1f22 fca3 93ab 3ae8 b..DS6r.."....:.
00000050: 3f7b 1b49 3682 1cc3 354b ef43 f9d4 1d6c ?{.I6...5K.C...l
00000060: ee8b 8dd1 a58f 553f db68 c12f c23f 9b31 ......U?.h./.?.1
00000070: f97c 015f 5519 b43d 58ff 32a3 dea7 62cd .|._U..=X.2...b.
00000080: ea28 c863 3253 2302 0102 .(.c2S#...
此编码方法使用 TLV
方案,即 Tag
、Length
和 Value
方案来编码有关块的信息。
第一个字节 0x30
是 TAG
,这是 SEQUENCE
的标识符。
第二个字节 0x81
是 LENGTH
,它告诉 TAG
保存的值的长度。在这种情况下,它是 0x81 或 0b10000001
。如果您看到,第一位设置为 1
,这意味着 TAG
所持有的长度超过 127,编码该长度所需的实际字节数在位 6 到位 1 中,在本例中为 1
。因此,我们也读取接下来的 1 个字节以找到实际长度,即 0x87
.
现在 VALUE
必须开始了。我们再次回到 TLV
。下一个字节是 0x02
代表 INTEGER
.
下一个字节是0x81
,也就是说value的长度大于127。所以我们读取下一个字节来找出当前标签中存储的value的长度。下一个字节是0x81
,所以当前TAG
中值的长度是0x81
或129
字节。
我们读取接下来的 129 个字节(任何未标记为 x
的字节)
00000000: xxxx xxxx xxxx 0094 b412 216d 42b9 e31a 0.........!mB...
00000010: 15de 0aee b64b 41fa 8fde 441e eaa2 a29c .....KA...D.....
00000020: b228 4719 88f8 650a e609 58c3 6969 b4d5 .(G...e...X.ii..
00000030: d4d2 b521 4d1f 9ba9 7858 3794 0f6e 5100 ...!M...xX7..nQ.
00000040: 62e5 d244 5336 7299 1f22 fca3 93ab 3ae8 b..DS6r.."....:.
00000050: 3f7b 1b49 3682 1cc3 354b ef43 f9d4 1d6c ?{.I6...5K.C...l
00000060: ee8b 8dd1 a58f 553f db68 c12f c23f 9b31 ......U?.h./.?.1
00000070: f97c 015f 5519 b43d 58ff 32a3 dea7 62cd .|._U..=X.2...b.
00000080: ea28 c863 3253 23xx xxxx .(.c2S#...
如果您现在匹配,您将看到准确的素数。您也可以继续阅读以发现生成器 0x02
。
从下面看,为什么素数和xxd hex不一样? 我正在尝试生成自己的参数,但不确定这些值的数学运算是什么...
[root@localhost]# openssl dh -in dhp.pem -text
DH Parameters: (1024 bit)
prime:
00:94:b4:12:21:6d:42:b9:e3:1a:15:de:0a:ee:b6:
4b:41:fa:8f:de:44:1e:ea:a2:a2:9c:b2:28:47:19:
88:f8:65:0a:e6:09:58:c3:69:69:b4:d5:d4:d2:b5:
21:4d:1f:9b:a9:78:58:37:94:0f:6e:51:00:62:e5:
d2:44:53:36:72:99:1f:22:fc:a3:93:ab:3a:e8:3f:
7b:1b:49:36:82:1c:c3:35:4b:ef:43:f9:d4:1d:6c:
ee:8b:8d:d1:a5:8f:55:3f:db:68:c1:2f:c2:3f:9b:
31:f9:7c:01:5f:55:19:b4:3d:58:ff:32:a3:de:a7:
62:cd:ea:28:c8:63:32:53:23
generator: 2 (0x2)
-----BEGIN DH PARAMETERS-----
MIGHAoGBAJS0EiFtQrnjGhXeCu62S0H6j95EHuqiopyyKEcZiPhlCuYJWMNpabTV
1NK1IU0fm6l4WDeUD25RAGLl0kRTNnKZHyL8o5OrOug/extJNoIcwzVL70P51B1s
7ouN0aWPVT/baMEvwj+bMfl8AV9VGbQ9WP8yo96nYs3qKMhjMlMjAgEC
-----END DH PARAMETERS-----
[root@localhost]# xxd dhp.pem
0000000: 2d2d 2d2d 2d42 4547 494e 2044 4820 5041 -----BEGIN DH PA
0000010: 5241 4d45 5445 5253 2d2d 2d2d 2d0a 4d49 RAMETERS-----.MI
0000020: 4748 416f 4742 414a 5330 4569 4674 5172 GHAoGBAJS0EiFtQr
0000030: 6e6a 4768 5865 4375 3632 5330 4836 6a39 njGhXeCu62S0H6j9
0000040: 3545 4875 7169 6f70 7979 4b45 635a 6950 5EHuqiopyyKEcZiP
0000050: 686c 4375 594a 574d 4e70 6162 5456 0a31 hlCuYJWMNpabTV.1
0000060: 4e4b 3149 5530 666d 366c 3457 4465 5544 NK1IU0fm6l4WDeUD
0000070: 3235 5241 474c 6c30 6b52 544e 6e4b 5a48 25RAGLl0kRTNnKZH
0000080: 794c 386f 354f 724f 7567 2f65 7874 4a4e yL8o5OrOug/extJN
0000090: 6f49 6377 7a56 4c37 3050 3531 4231 730a oIcwzVL70P51B1s.
00000a0: 376f 754e 3061 5750 5654 2f62 614d 4576 7ouN0aWPVT/baMEv
00000b0: 776a 2b62 4d66 6c38 4156 3956 4762 5139 wj+bMfl8AV9VGbQ9
00000c0: 5750 3879 6f39 366e 5973 3371 4b4d 686a WP8yo96nYs3qKMhj
00000d0: 4d6c 4d6a 4167 4543 0a2d 2d2d 2d2d 454e MlMjAgEC.-----EN
00000e0: 4420 4448 2050 4152 414d 4554 4552 532d D DH PARAMETERS-
00000f0: 2d2d 2d2d 0a ----.
这 2 个命令的输出完全不相关。 openssl
命令打印 pem 文件中包含的信息,xxd
命令打印文件的原始十六进制转储。
该文件包含素数,但采用名为 Privacy Enhanced Mail format, or PEM
for short. It's a human readable base64 encoded format of a binary blob which contains any piece of information packed according to ASN.1 的编码格式。
如果您尝试解析 pem 文件,即根据 ASN.1 结构解码二进制文件,您将看到以下内容:
$ openssl asn1parse -in dh.pem -inform PEM -i
0:d=0 hl=3 l= 135 cons: SEQUENCE
3:d=1 hl=3 l= 129 prim: INTEGER :94B412216D42B9E31A15DE0AEEB64B41FA8FDE441EEAA2A29CB228471988F8650AE60958C36969B4D5D4D2B5214D1F9BA9785837940F6E510062E5D244533672991F22FCA393AB3AE83F7B1B4936821CC3354BEF43F9D41D6CEE8B8DD1A58F553FDB68C12FC23F9B31F97C015F5519B43D58FF32A3DEA762CDEA28C863325323
135:d=1 hl=2 l= 1 prim: INTEGER :02
这是实际打包到二进制文件中的内容。 openssl dh
命令只是将数据解释为更易读的详细形式。目前,我无法找到表示打包 DH 参数结构的实际结构。
要真正在 xxd 输出中看到素数,需要做更多的工作,但这不是很困难。
$ cat << EOF | base64 -d | xxd
> MIGHAoGBAJS0EiFtQrnjGhXeCu62S0H6j95EHuqiopyyKEcZiPhlCuYJWMNpabTV
> 1NK1IU0fm6l4WDeUD25RAGLl0kRTNnKZHyL8o5OrOug/extJNoIcwzVL70P51B1s
> 7ouN0aWPVT/baMEvwj+bMfl8AV9VGbQ9WP8yo96nYs3qKMhjMlMjAgEC
> EOF
00000000: 3081 8702 8181 0094 b412 216d 42b9 e31a 0.........!mB...
00000010: 15de 0aee b64b 41fa 8fde 441e eaa2 a29c .....KA...D.....
00000020: b228 4719 88f8 650a e609 58c3 6969 b4d5 .(G...e...X.ii..
00000030: d4d2 b521 4d1f 9ba9 7858 3794 0f6e 5100 ...!M...xX7..nQ.
00000040: 62e5 d244 5336 7299 1f22 fca3 93ab 3ae8 b..DS6r.."....:.
00000050: 3f7b 1b49 3682 1cc3 354b ef43 f9d4 1d6c ?{.I6...5K.C...l
00000060: ee8b 8dd1 a58f 553f db68 c12f c23f 9b31 ......U?.h./.?.1
00000070: f97c 015f 5519 b43d 58ff 32a3 dea7 62cd .|._U..=X.2...b.
00000080: ea28 c863 3253 2302 0102 .(.c2S#...
此编码方法使用 TLV
方案,即 Tag
、Length
和 Value
方案来编码有关块的信息。
第一个字节 0x30
是 TAG
,这是 SEQUENCE
的标识符。
第二个字节 0x81
是 LENGTH
,它告诉 TAG
保存的值的长度。在这种情况下,它是 0x81 或 0b10000001
。如果您看到,第一位设置为 1
,这意味着 TAG
所持有的长度超过 127,编码该长度所需的实际字节数在位 6 到位 1 中,在本例中为 1
。因此,我们也读取接下来的 1 个字节以找到实际长度,即 0x87
.
现在 VALUE
必须开始了。我们再次回到 TLV
。下一个字节是 0x02
代表 INTEGER
.
下一个字节是0x81
,也就是说value的长度大于127。所以我们读取下一个字节来找出当前标签中存储的value的长度。下一个字节是0x81
,所以当前TAG
中值的长度是0x81
或129
字节。
我们读取接下来的 129 个字节(任何未标记为 x
的字节)
00000000: xxxx xxxx xxxx 0094 b412 216d 42b9 e31a 0.........!mB...
00000010: 15de 0aee b64b 41fa 8fde 441e eaa2 a29c .....KA...D.....
00000020: b228 4719 88f8 650a e609 58c3 6969 b4d5 .(G...e...X.ii..
00000030: d4d2 b521 4d1f 9ba9 7858 3794 0f6e 5100 ...!M...xX7..nQ.
00000040: 62e5 d244 5336 7299 1f22 fca3 93ab 3ae8 b..DS6r.."....:.
00000050: 3f7b 1b49 3682 1cc3 354b ef43 f9d4 1d6c ?{.I6...5K.C...l
00000060: ee8b 8dd1 a58f 553f db68 c12f c23f 9b31 ......U?.h./.?.1
00000070: f97c 015f 5519 b43d 58ff 32a3 dea7 62cd .|._U..=X.2...b.
00000080: ea28 c863 3253 23xx xxxx .(.c2S#...
如果您现在匹配,您将看到准确的素数。您也可以继续阅读以发现生成器 0x02
。