实现Diffie-Hellman密钥交换时,预主密钥不匹配

jaw*_*awr 42 ssl cryptography go diffie-hellman

我正在尝试将DHE_DSS实现到go的crypto/tls包中.不幸的是,我似乎无法使PreMasterSecret(Z)变得相同,我的基本工作流程是:

接收服务器密钥交换消息

  • 提取P,G,Ys
  • 使用提供的数字签名验证

准备客户端密钥交换消息

  • 创建客户端的Xc
  • 生成Yc(Yc = G ^ Xc%P)
  • 生成Z(Z = Ys ^ Xc%P)
  • 发回Yc,包装如下:
ckx := make([]byte, len(yC)+2)
ckx[0] = byte(len(Yc)>>8)
ckx[1] = byte(len(Yc))
copy(ckx[2:], yBytes)
Run Code Online (Sandbox Code Playgroud)

但是,当我使用gnutls-serv进行调试时,两个PreMasterSecrets(Z)是不同的.我是否需要签署退回的Yc,或者以其他方式包装?我在RFC 5246中看不到任何建议.

< - 编辑 - >

以下是我的更改补丁:

https://08766345559465695203.googlegroups.com/attach/48587532c74b4348/crypto.patch?part=4&view=1&vt=ANaJVrHbwydqEZc3zjUWqQ5C8Q5zEkWXZLdL0w6JJG3HYntOlBurUTY7mc9xR9OTfE0bJxs4eeL5a5SGd2jj9eIfXcwJQgLvJchXOgkYKBBynbPfshY8kuQ

Nar*_*hai 1

客户端密钥交换将包含:

length (2 bytes) --> Y_C (in plain text)
Run Code Online (Sandbox Code Playgroud)

我已经在 J​​ava 中实现了 TLS,并且遵循相同的结构并且对我来说工作得很好。

我需要在退回的 Yc 上签名吗?

不需要对客户端DH公共值进行签名,它以明文形式传输。

您可以采取 pcap 并检查数据包中是否传输相同的值。此外,如果 GNU TLS 有用于打印接收Y_C到的数据的记录器,那么您可以检查是否收到了正确的数据。

如果您仍然获得不同的 Pre-Master 秘密,那么秘密的生成逻辑似乎存在一些问题。