![使用 openssl 命令行工具解密 SSL 流量 - 续](https://linux22.com/image/1566397/%E4%BD%BF%E7%94%A8%20openssl%20%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7%E8%A7%A3%E5%AF%86%20SSL%20%E6%B5%81%E9%87%8F%20-%20%E7%BB%AD.png)
我得到了我最初问题的答案
这里
希望可以通过发布另一个问题来提出后续问题。从我上面的原始问题中,我能够使用我的私钥解密客户端预主密钥/密钥,正如使用
openssl rsautl -in cpre.key -inkey key.pem -decrypt -out spre.key向我解释的
那样,这似乎非常简单,它创建了一个 48 字节的文件。我确实意识到我正在做的并不是真正解密或加密 https 流量,我正在分小步进行这项工作。从我阅读的下一步将是生成主密钥/密钥,从我之前帖子的答案来看,似乎我也应该能够使用 openssl 来做到这一点,我在这里有点挣扎。我想出了一个 openssl dgst
echo -n 'value' | openssl dgst -sha256 -mac hmac -macopt hexkey:$(hexkey)的变体
,其中值是“主密钥”+client.random+server.random,hexkey 是我在上一步解密的预主密钥。我是否正确执行了此步骤?根据我对 RFC 的理解,因为第一次执行时会产生 32 个字节,而 RFC 解释为 48 个字节。我对 RFC 的解释是,我需要获取该结果并再次传递,这会生成额外的 32 个字节,我取其中的前 16 个字节并将其连接到前 32 个字节的末尾以获得我的 48 个字节作为主密钥。解密并获得服务器端预主密钥后,我是否完全偏离了下一步?谢谢 David B
答案1
首先,我希望你没有真正做你所展示的事情。除了标签之外,TLS 密钥派生中使用的所有数据都是二进制数据,无法准确地作为参数提供给 shell 命令echo
或任何其他命令,除非zsh
你禁用转义,否则可能是内置版本,并且肯定不能在带单引号的文字参数中“输入”(甚至剪切和粘贴)。
如果您确实有文件中的数据,那么可以使用它们。可以从文件读取和写入二进制数据 - 至少在 OpenSSL 支持的平台上。如果您没有文件(但有管道),您可以通过传递十六进制数据来解决这个问题,并且除了-macopt hexkey:
已经接受十六进制的之外,使用像 这样的程序xxd -r
,或printf
将十六进制转换成转义符,或echo
将十六进制转换成不可移植的转义符,或像 GNU 这样的黑客sed s///e
,或更通用的程序awk
或perl
,将十六进制转换为二进制以输入到openssl
。并且在必要时使用类似的黑客将二进制输出转换为十六进制,但dgst -mac hmac
只要blahblah=(sp)
从前面删除 就可以以十六进制输出。
更实质上,将第一个 HMAC 输出通过其自身运行只会为您提供“A”块,然后您再通过另一层 HMAC 运行该块以获得实际输出“P_hash”。请参阅https://crypto.stackexchange.com/questions/46549/tls-1-2-prf-with-hmac-sha256这实际上是使用在https://www.ietf.org/mail-archive/web/tls/current/msg03416.html但我是用 Java 回答的。以下是 OpenSSL 命令行等效项:
$ echo $key; echo $lbsd # start from hex
9bbe436ba940f017b17652849a71db35
74657374206c6162656c a0ba9f936cda311827a6f796ffd5198c
$ echo $lbsd | xxd -r -p >a0
$ openssl dgst -sha256 -mac hmac -macopt hexkey:$key <a0 -binary >a1
$ openssl dgst -sha256 -mac hmac -macopt hexkey:$key <a1 -binary >a2
$ openssl dgst -sha256 -mac hmac -macopt hexkey:$key <a2 -binary >a3
$ openssl dgst -sha256 -mac hmac -macopt hexkey:$key <a3 -binary >a4
$ cat a1 a0 | openssl dgst -sha256 -mac hmac -macopt hexkey:$key -binary >k1
$ cat a2 a0 | openssl dgst -sha256 -mac hmac -macopt hexkey:$key -binary >k2
$ cat a3 a0 | openssl dgst -sha256 -mac hmac -macopt hexkey:$key -binary >k3
$ cat a4 a0 | openssl dgst -sha256 -mac hmac -macopt hexkey:$key -binary >k4
$ cat k1 k2 k3 k4 | head -c100 | xxd
0000000: e3f2 29ba 727b e17b 8d12 2620 557c d453 ..).r{.{..& U|.S
0000010: c2aa b21d 07c3 d495 329b 52d4 e61e db5a ........2.R....Z
0000020: 6b30 1791 e90d 35c9 c9a4 6b4e 14ba f9af k0....5...kN....
0000030: 0fa0 22f7 077d ef17 abfd 3797 c056 4bab .."..}....7..VK.
0000040: 4fbc 9166 6e9d ef9b 97fc e34f 7967 89ba O..fn......Oyg..
0000050: a480 82d1 22ee 42c5 a72e 5a51 10ff f701 ....".B...ZQ....
0000060: 8734 7b66 .4{f
如果您可以让您的代码复制这一点,它也应该适用于实际的 TLS1.2 握手,并调整为正确的长度:主密钥为 48,并且取决于工作密钥的密码套件。