我想验证使用ECDHE接收的椭圆曲线公钥上的签名,但是我找不到任何明确解释签名的字节的参考。
我设置了一个TLS v1.2连接到google.com使用密码套件TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)。我用Wireshark捕获了流量,我可以看到客户端你好、服务器你好、证书和服务器密钥交换消息。我的理解是Google发送的EC公钥是使用Google发送的证书的私钥(在本例中是RSA)签名的。
服务器密钥交换消息:
160303014 d0c0001 490300174104 f930
e65768e0587ec7e1 b8b537ccd6ae2500
3 a364b84a68ed7c0 47 d18dd104afb63c
cc72e800495db3cd d629807f0d4501a4
c043c5c7c52aea45 a66692aa11b60201
01007 ec0b1ef4994 30 f42f3ed9a7a592
92 c0f875ad7cd2f8 b36a7aec804f602
5825 a8a3d0e5c 2959549 fefa4d69f360
34 eaad7138e5da69 61 bdfb88ddb5172c
ba64071de0764fc1 c8b895dbc52ec85c
3 b7891c53e6d843b 44 f80c481a9beb86 6665年c444b32204e9bc6c e6dd26887c5e
686年fc4e331fbdd66536 b6b5f16072b52
ee2fee75ca65e28f a0ee0644b91fba30
394 aa83cf28f1 783798 b1344b43104cb
89 aed55030bd7561 d13ae20d4d7bc17e
682 e6c6266f04bf6 31665 a547e2f15b3
c79fda548a781d39 5 d64f4eea75aac96
9374 ce60400fdc11 a3d5a98b62f63b7
6 e5324797c938f39 bc1cc5736b612bd7
7 a1bc790841d4e25 dae648cab33273e2
588 c解析得到:
160303014d -记录头
0c -服务器密钥交换消息
000149 -消息长度
03 -命名曲线
0017 - secp256r1曲线
41 -公钥长度
04 -不知道这是什么意思
f930e6……04af[32字节]-公钥的x值
b63ccc……11b6[32字节]-公钥的y值
2 - SHA-1哈希
01 - RSA签名
0100 -签名长度
7 ec0b1……588c[256字节]-签名值
使用我在证书消息中收到的证书,我能够对EC公钥的签名执行公钥操作,它看起来像一个适当填充的SHA-1哈希。但是,我无法验证这个哈希值。我尝试了许多不同的原始EC公钥及其头的组合,但没有尝试正确的散列。
下面是我如何获取哈希值:openssl rsautl -inkey ~/googlePubKey。pem -encrypt -in ~/googleECpubkeysig -pubin -raw | hexdump
0000000 0100 FFFF FFFF FFFF FFFF FFFF FFFF FFFF
0000010 FFFF FFFF FFFF FFFF FFFF FFFF FFFF
*00000d0 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的参考资料和这篇相关的文章,在其中一个评论中提到了两个随机值: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
当我使用这个值时,哈希匹配并且签名验证OK