我正在尝试通过提供一个包含Rand
字段的tls.Config
结构来建立TLS连接,该字段在调用其Read
方法时应始终返回相同的int
,请参阅此处的文档: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()
我希望在提供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>
哪里:
<FIRST_LONG_ID>
总是相同的<SECOND_LONG_ID>
在每次执行后都会发生变化
当为来自不同执行的一批数据包提供密钥文件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
输入切片的所有元素。
但是,我仍然生成SSL密钥,这些密钥对于不同的执行具有不同的<SECOND_LONG_ID>
值。
在分析这些加密的TCP数据包时,是否有可能让Wireshark在不同的TLS连接上重复使用SSL密钥?
您使用的读错了。您的测试不会测试您认为它的作用。firstNum 和 secondNum 都是 3,因为您正在读取三个随机字节;因为您正在传递长度为三的字节片。但是,您永远不会检查实际的随机字节。