使用 openssl 命令行工具解密 SSL 流量 - 续第 3 部分

使用 openssl 命令行工具解密 SSL 流量 - 续第 3 部分

从我之前的问题/话题开始第1部分并跟进第2部分按照我的指导说明,由于我捕获的文件/数据本质上是二进制的,因此我使用了以下 openssl 命令,其中我从以下位置派生出的预主密钥开始:

openssl rsautl -in cpre.key -inkey key.pem -decrypt -out spre.key

这创建了我的 48 字节服务器预主密钥文件spre.key(我认为是正确的)并以十进制表示(使用 bed 查看):

003 003 203 048 063 215 047 196 221 221 221 014 019 072 011 100 217 080 111 073 217 026 234 082 022 217 232 025 096 063 115 080 016 094 015 170 148 126 092 118 109 228 246 149 208 195 044 220

十六进制: 0303CB303FD72FC4DDDDDD0E13480B64D9506F49D91AEA5216D9E819603F7350105E0FAA947E5C766DE4F695D0C32CDC

并将我创建的文字“master secret”+client.random+server.random 连接起来种子密钥并再次以与我创建的十进制相同的方式使用 bed 查看:

109 097 115 116 101 114 032 115 101 099 114 101 116 173 212 147 215 014 129 225 102 157 027 001 125 167 097 014 085 064 025 114 025 024 248 096 254 044 235 151 130 033 151 015 133 251 114 232 095 213 076 194 057 175 106 225 088 206 069 187 050 168 031 217 080 198 061 180 043

十六进制:6D617374657220736563726574ADD493D70E81E1669D1B017DA7610E554019721918F860FE2CEB978221970F85FB72E85FD54CC239AF6AE158CE45BB32A81FD950C63DB42B
,总共 69 个字节

接下来我将它们放在一起,由于我被告知数据在二进制文件中,因此我使用以下命令生成主密钥和密钥。

openssl dgst -sha256 -hmac spre.key <mseed.key -binary >a1
openssl dgst -sha256 -hmac spre.key <a1 -binary >a2
openssl dgst -sha256 -hmac spre.key <a2 -binary >a3
openssl dgst -sha256 -hmac spre.key <a3 -binary >a4

这创建了 4 个 32 字节文件。

接下来使用以下命令创建密钥:

cat a1 mseed.key | openssl dgst -sha256 -hmac spre.key -binary >k1
cat a2 mseed.key | openssl dgst -sha256 -hmac spre.key -binary >k2
cat a3 mseed.key | openssl dgst -sha256 -hmac spre.key -binary >k3
cat 42 mseed.key | openssl dgst -sha256 -hmac spre.key -binary >k4

这创建了 4 个 32 字节文件。

按照我给出的示例并阅读 RFC,据我所知,此时的主密钥将是 a1+a2 的前 48 个字节,这是正确的吗?还是我错过了什么?由于我实际上无法看到 master_secret PRF 返回的内容或正在执行的操作,我认为通过运行上述命令行,这就是我获取主密钥的方法。谢谢 David

答案1

首先,您的 mseed 文件(PRF 中的标签+种子值)应该是 77 字节,而不是 69 字节。您一定是以某种方式弄乱了客户端和/或服务器 nonce。

第二,-hmac spre.key这是非常错误的。它利用了实际的人物 s p r e . k e y即八位字节 73 70 72 65 2e 6b 65 79 作为 HMAC 密钥。您需要使用解密的预主密钥的值,即内容spre.key 文件的。由于这是二进制数据,可能包含特殊字符代码(如 null、制表符、美元符号、引号、反斜杠、删除等)的字节,因此您无法安全地直接传递它,就像-hmac {key}或 甚至 一样-hmac '{key}';相反,您需要使用-mac hmac -macopt hexkey:{hex key value}我在上一个答案中显示的方法,但要使用您在此问题中显示的实际十六进制密钥值,即0303CB30...2CDC

第三,正如我在上一个答案中所展示的那样,你将第二HMAC 层,即我的符号 k1,k2,... 形成输出(在该示例中为 100 个八位字节):

$ cat k1 k2 k3 k4 | head -c100 | xxd

但正如我接着说的:

... 对于实际的 TLS1.2 握手,也调整为正确的长度:主密钥为 48,并且取决于工作密钥的密码套件。

对于第一个(预主到主)派生,您需要 48 个八位字节,因此您只需要前两个 32 块(a0->a1->a2 a1+a0->k1 a2+a0->k2),然后连接加权并取前48个八位字节。

对于第二个(主服务器到工作服务器)派生,所需的长度取决于协商的密码套件。您说您正在使用 RSA-with-AES256CBC-SHA,它(在 TLS1.2 或 1.1 中,但不是 1.0)需要 40 个八位字节的 HMAC 密钥和 64 个八位字节的加密密钥,总共 104 个八位字节。对于 104 个八位字节,您需要计算 4 个 32 块,连接 k1+k2+k3+k4,然后按顺序将其分发到客户端 MAC、服务器 MAC、客户端加密、服务器加密。请参阅 RFC 的 6.3。另请注意,标签不同,对于此派生,种子是 (label+)server_random+client_random,而不是第一个中的 (label+)client_random+server_random。

相关内容