ssl - 通过存储与 Wireshark 一起使用的 SSL key 在 golang 中解密 TLS

标签 ssl go wireshark tls1.2 nss

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

我写了这个构建器:

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

并进行测试以确保 rand.Rand总是返回相同的 int什么时候Read被多次调用,注意不同的输入参数 "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()我期望在文件 same-key.log 中始终生成相同的 SSL key 当提供这样的 TLS 配置时:

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 key 日志格式中找到此处描述的结构:https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format

CLIENT_RANDOM <FIRST_LONG_ID> <SECOND_LONG_ID>

哪里:

  • <FIRST_LONG_ID>总是一样的
  • <SECOND_LONG_ID>每次执行后都会改变 <-- 为什么会这样?

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

我可能在这里误解了一些关于 SSL 加密的内部机制,我想知道我是否也应该在配置结构中提供证书?我如何生成这些证书?

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

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

编辑:

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

我想出了这个 Read tls.Config 的实现结构:

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输入 slice 的所有元素。

但是我仍然生成具有不同 <SECOND_LONG_ID> 的 SSL key 不同执行的值。

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

最佳答案

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

关于ssl - 通过存储与 Wireshark 一起使用的 SSL key 在 golang 中解密 TLS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47476852/

相关文章:

WCF 服务和 Thinktecture Identity 服务器

python - urllib3 CERTIFICATE_VERIFY_FAILED 在某些具有有效证书的站点上

arrays - 从 JSON 数组列表中检索未知的键名和值

networking - 重置 RST 标志后的 TCP 重传

android - 小米手环 2 可以检测触摸吗?

java - 签名算法 : SHA256WithRSAEncryption 上的算法约束检查失败

java - 我在简单的 Web 抓取工具中遇到 SSL 握手 fatal error

go - 如何使用 Go 优雅地解析 URI?

go - 尽管选项响应中出现“Access-Control-Allow-Origin” header ,stilll却出现cors错误

http - 我可以同时使用 Proxifier 和 Fiddler 吗?