【问题标题】:Decrypt TLS in golang by storing SSL key to be used with Wireshark通过存储要与 Wireshark 一起使用的 SSL 密钥来解密 golang 中的 TLS
【发布时间】:2018-05-08 16:19:13
【问题描述】:

我正在尝试通过提供一个包含 Rand 字段的 tls.Config 结构来建立 TLS 连接,该字段在调用 Read 方法时应始终返回相同的 int,参见。此处的文档:https://golang.org/pkg/crypto/tls/#Config

我已经编写了这个构建器:

func newZeroRand() *rand.Rand {
    return rand.New(rand.NewSource(0))
}

Read 被多次调用时,测试确保rand.Rand 总是返回相同的int,注意不同的输入参数"foo""bar" 提供相同的输出:

func TestPredictableZeroRandGenerator(t *testing.T) {
    zeroRand := newZeroRand()
    firstNum, err := zeroRand.Read([]byte("foo"))
    if err != nil {
        t.Error(err)
    }
    secondNum, err := zeroRand.Read([]byte("bar"))
    if err != nil {
        t.Error(err)
    }

    // fmt.Printf("firstNum %d secondNum %d \n", firstNum, secondNum)
    if firstNum != secondNum {
        t.Error(fmt.Sprintf("This is not a predictable zero random generator! The first number is: %d the second number is: %d", firstNum, secondNum))
    }
}

使用之前定义的 newZeroRand(),当提供这样的 TLS 配置时,我希望在文件 same-key.log 中始终生成相同的 SSL 密钥:

func tlsConfig() (*tls.Config, error) {
    w, err := os.OpenFile("same-key.log", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
    if err != nil {
        return nil, err
    }
    tlsConfig := tls.Config{
        Rand: newZeroRand(),
        KeyLogWriter: w,
    }
    return &tlsConfig, nil
}

但对于多次执行,我得到不同的文件内容。我可能会误解这里的细节:https://golang.org/pkg/crypto/tls/#example_Config_keyLogWriter 因为当我在每次执行后打开这些文件时same-key.log 然后我在 Mozilla 的 NSS 密钥日志格式中找到此处描述的结构:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format

CLIENT_RANDOM <FIRST_LONG_ID> <SECOND_LONG_ID>

地点:

  • &lt;FIRST_LONG_ID&gt; 总是一样的
  • &lt;SECOND_LONG_ID&gt; 在每次执行后都会发生变化

当为来自不同执行的一批数据包提供密钥文件 same-key.log 时,Wireshark 无法解密它们!

我可能在这里误解了一些关于 SSL 加密的内部知识,我想知道我是否还应该在配置结构中提供证书?我怎样才能生成这些证书?

Afaik 在密钥之上使用证书时,在运行时应该有一条来自另一方的信息,因此如果我没有该信息,我将无法解密数据包流。这就是为什么我认为如果我想使用 Wireshark 来解密这些数据包就不需要证书。

否则我不确定如何强制 TCP 连接始终使用相同的密钥加密/解密数据包?

编辑:

正如@peter 在他的回答中所指出的,我断言的是输入字节片的长度,而不是实际的“确定性随机值”。

我为tls.Config 结构提出了这个Read 实现:

type debugRand struct {}
func (dr *debugRand) Read(p []byte) (n int, err error) {
    for i := range p {
        p[i] = byte(0)
    }
    return len(p), nil
}
func newZeroRand() *debugRand {
    return &debugRand{}
}

这是设置为0 输入切片的所有元素。

但是,我仍然会为不同的执行生成具有不同 &lt;SECOND_LONG_ID&gt; 值的 SSL 密钥。

在分析那些加密的 TCP 数据包时,是否有可能让 Wireshark 在不同的 TLS 连接上重新使用 SSL 密钥?

【问题讨论】:

  • 您是否想出这个或任何其他方式来解密流量?我肯定错过了一些微不足道的东西,或者没有人以这种方式解密流量:P

标签: ssl go wireshark tls1.2 nss


【解决方案1】:

您使用 Read 错误。您的测试不会测试您认为它会做什么。 firstNum 和 secondNum 都是 3,因为您正在读取三个随机字节;因为您正在传递长度为 3 的字节片。但是,您永远不会检查实际的随机字节。

【讨论】:

  • 感谢您,我已经编辑了问题,提供了更多详细信息。
猜你喜欢
  • 2014-02-07
  • 1970-01-01
  • 2019-12-09
  • 2020-11-01
  • 1970-01-01
  • 2018-12-31
  • 2020-12-15
  • 1970-01-01
  • 2012-05-01
相关资源
最近更新 更多