Q1。为什么要两套关键材料?
在第 8:3 节中,他们说我们创建了 2 个 MAC 密钥和 2 个密钥。如果客户端和服务器使用相同的密钥和 MAC 密钥,这还不够安全吗?(假设这些密钥是从不少于 MasterSecret 生成的)。我觉得它似乎有点过度保护..
不,这是出于严重的原因。这使得它实际上更难攻击。有一类攻击,你只是将一方所说的话反映给自己。这称为反射攻击。通过使用方向固定键,您可以使此类攻击成为不可能。
Q2。如何砍断关键块?
拥有 MasterSecret 后,如何扩展它以创建 MAC 密钥和密钥?我怀疑我们只是将前 N 个字节用于密钥,其余的用于 MAC 密钥
很抱歉让你失望了,但事实就是这样。这里没有太多的魔法。
您有一个长八位字节字符串的密钥块。然后您只需将其切成 6 个较小的部分。
RFC
这是TLS 1.2 RFC 中的部分:
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
所以这是六个部分。并且按照这个确切的顺序。奇数条目 (1, 3, 5) 用于client_write
方向。甚至条目 (2, 4, 6) 都用于server_write
方向。
OpenSSL
这是 OpenSSL 中的切碎位:
这被分成:
ms
, MAC 秘密
key
, 批量加密密钥
iv
, 初始化向量
来自OpenSSL 的t1_enc.c
源代码:
if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
(which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
ms = &(p[0]);
n = i + i;
key = &(p[n]);
n += j + j;
iv = &(p[n]);
n += k + k;
exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
client_write = 1;
} else {
n = i;
ms = &(p[n]);
n += i + j;
key = &(p[n]);
n += j + k;
iv = &(p[n]);
n += k;
exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
client_write = 0;
}
我不会说C太好。所以我真的不明白。
- 我不明白索引到
p
.
- 我不明白他们为什么只选择一半的键。每一端都需要两套。一组写入另一端。一组读取另一端所说的内容。——我猜砍伐发生在其他地方。