如何验证 RSA-signed ECDHE public 密钥?
How to validate RSA-signed ECDHE public key?
我想验证使用 ECDHE 收到的椭圆曲线 public 密钥上的签名,但我找不到任何参考资料可以清楚地说明哪些字节已签名。
我使用密码套件 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 建立了到 google.com 的 TLS v1.2 连接。我用 Wireshark 捕获了流量,我可以看到客户端问候语、服务器问候语、证书和服务器密钥交换消息。我的理解是 Google 发送的 EC public 密钥是使用发送的证书 Google 的私钥签名的(在本例中为 RSA)。
这是服务器密钥交换消息:
160303014d0c0001 490300174104f930
e65768e0587ec7e1 b8b537ccd6ae2500
3a364b84a68ed7c0 47d18dd104afb63c
cc72e800495db3cd d629807f0d4501a4
c043c5c7c52aea45 a66692aa11b60201
01007ec0b1ef4994 30f42f3ed9a7a592
92c0f875ad7cd2f8 5b36a7aec804f602
2959549a8a3d0e5c 5825fefa4d69f360
34eaad7138e5da69 61bdfb88ddb5172c
ba64071de0764fc1 c8b895dbc52ec85c
3b7891c53e6d843b 44f80c481a9beb86
c444b32204e9bc6c 6665e6dd26887c5e
fc4e331fbdd66536 686b6b5f16072b52
ee2fee75ca65e28f a0ee0644b91fba30
783798aa83cf28f1 394b1344b43104cb
89aed55030bd7561 d13ae20d4d7bc17e
682e6c6266f04bf6 31665a547e2f15b3
c79fda548a781d39 5d64f4eea75aac96
9374ce60400fdc11 3a3d5a98b62f63b7
6e5324797c938f39 bc1cc5736b612bd7
7a1bc790841d4e25 dae648cab33273e2
588c
解析后得到:
160303014d - 记录 header
0c - 服务器密钥交换消息
000149 - 消息长度
03 - 命名曲线
0017 - secp256r1 曲线
41 - public 键的长度
04 - 不确定这是什么意思
f930e6...04af [32 字节] - public 键的 x 值
b63ccc...11b6 [32 字节] - public 键的 y 值
02 - SHA-1 哈希
01 - RSA 签名
0100 - 签名长度
7ec0b1...588c [256 字节] - 签名值
使用我在证书消息中收到的证书,我能够对 EC public 密钥的签名执行 public 密钥操作,它看起来像一个正确填充的 SHA-1哈希。但是,我无法验证此哈希值。我尝试了原始 EC public 密钥与其 header 的许多不同组合,但我没有正确尝试哈希。
这是我检索哈希的方法:
openssl rsautl -inkey ~/googlePubKey.pem -encrypt -in ~/googleECpubkeysig -pubin -raw |十六进制转储
0000000 0100 ffff ffff ffff ffff ffff ffff ffff
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000d0 ffff ffff ffff ffff ffff ffff 3000 3021
00000e0 0609 2b05 030e 1a02 0005 1404 3ac5 fb13
00000f0 9ff8 77f1 6a69 09af 472a 90b2 cac6 b4f8
0000100
最后 20 个字节看起来像 SHA-1 哈希,这是签名中指定的算法。我应该对来自服务器密钥交换的哪些字节进行哈希处理以获得该值?或者,是否存在我必须在散列之前执行或添加的某些转换或其他数据?
我缺少客户端随机和服务器随机。感谢 JamesKPolk 提供的参考资料和相关的 post 在其中一条评论中提到了两个随机值:https://security.stackexchange.com/questions/80619/tls-1-2-handshake-how-is-the-ecdhe-public-key-signed-by-server.
我上面的示例(括号中为十六进制值)的完整散列值是:
client_random(32 字节)+server_random(32 字节)+named_curve(0x03)+secp256r1_curve(0x0017)+length_of_public_key(0x41 ) + first_byte_of_key (0x04) + key_x_value + key_y_value
当我使用这个值时,哈希匹配并且签名验证正常。
我想验证使用 ECDHE 收到的椭圆曲线 public 密钥上的签名,但我找不到任何参考资料可以清楚地说明哪些字节已签名。
我使用密码套件 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) 建立了到 google.com 的 TLS v1.2 连接。我用 Wireshark 捕获了流量,我可以看到客户端问候语、服务器问候语、证书和服务器密钥交换消息。我的理解是 Google 发送的 EC public 密钥是使用发送的证书 Google 的私钥签名的(在本例中为 RSA)。
这是服务器密钥交换消息:
160303014d0c0001 490300174104f930
e65768e0587ec7e1 b8b537ccd6ae2500
3a364b84a68ed7c0 47d18dd104afb63c
cc72e800495db3cd d629807f0d4501a4
c043c5c7c52aea45 a66692aa11b60201
01007ec0b1ef4994 30f42f3ed9a7a592
92c0f875ad7cd2f8 5b36a7aec804f602
2959549a8a3d0e5c 5825fefa4d69f360
34eaad7138e5da69 61bdfb88ddb5172c
ba64071de0764fc1 c8b895dbc52ec85c
3b7891c53e6d843b 44f80c481a9beb86
c444b32204e9bc6c 6665e6dd26887c5e
fc4e331fbdd66536 686b6b5f16072b52
ee2fee75ca65e28f a0ee0644b91fba30
783798aa83cf28f1 394b1344b43104cb
89aed55030bd7561 d13ae20d4d7bc17e
682e6c6266f04bf6 31665a547e2f15b3
c79fda548a781d39 5d64f4eea75aac96
9374ce60400fdc11 3a3d5a98b62f63b7
6e5324797c938f39 bc1cc5736b612bd7
7a1bc790841d4e25 dae648cab33273e2
588c
解析后得到:
160303014d - 记录 header
0c - 服务器密钥交换消息
000149 - 消息长度
03 - 命名曲线
0017 - secp256r1 曲线
41 - public 键的长度
04 - 不确定这是什么意思
f930e6...04af [32 字节] - public 键的 x 值
b63ccc...11b6 [32 字节] - public 键的 y 值
02 - SHA-1 哈希
01 - RSA 签名
0100 - 签名长度
7ec0b1...588c [256 字节] - 签名值
使用我在证书消息中收到的证书,我能够对 EC public 密钥的签名执行 public 密钥操作,它看起来像一个正确填充的 SHA-1哈希。但是,我无法验证此哈希值。我尝试了原始 EC public 密钥与其 header 的许多不同组合,但我没有正确尝试哈希。
这是我检索哈希的方法:
openssl rsautl -inkey ~/googlePubKey.pem -encrypt -in ~/googleECpubkeysig -pubin -raw |十六进制转储
0000000 0100 ffff ffff ffff ffff ffff ffff ffff
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000d0 ffff ffff ffff ffff ffff ffff 3000 3021
00000e0 0609 2b05 030e 1a02 0005 1404 3ac5 fb13
00000f0 9ff8 77f1 6a69 09af 472a 90b2 cac6 b4f8
0000100
最后 20 个字节看起来像 SHA-1 哈希,这是签名中指定的算法。我应该对来自服务器密钥交换的哪些字节进行哈希处理以获得该值?或者,是否存在我必须在散列之前执行或添加的某些转换或其他数据?
我缺少客户端随机和服务器随机。感谢 JamesKPolk 提供的参考资料和相关的 post 在其中一条评论中提到了两个随机值:https://security.stackexchange.com/questions/80619/tls-1-2-handshake-how-is-the-ecdhe-public-key-signed-by-server.
我上面的示例(括号中为十六进制值)的完整散列值是:
client_random(32 字节)+server_random(32 字节)+named_curve(0x03)+secp256r1_curve(0x0017)+length_of_public_key(0x41 ) + first_byte_of_key (0x04) + key_x_value + key_y_value
当我使用这个值时,哈希匹配并且签名验证正常。