我知道对于大多数密码来说,一个好的随机数非常重要。我正在使用 AES-GCM,并且正在使用 96 位随机数和 256 位 AES 密钥。我之前在这里问过一些关于如何通过不安全的渠道协商随机数的问题。
我正在使用 ECDH 导出共享密钥,并计划使用 X9.63 标准方法从中导出密钥材料。我知道在协商密钥时可以将随机生成的 96 位附加到盐的末尾。然后我可以像 XOR 一样以某种方式将两者结合起来(这是一个点对点系统),并有一个随机的、好的随机数。
当然,这并不能阻止 MITM 攻击,比如通过 ARP 欺骗。公钥本身由中央服务器认证,其公钥与应用程序一起分发。因此,认证不能因为使用GCM而被篡改。但是,随机数当然没有经过认证,因此可以潜在地 MITM 对等方,保持他们的密钥相同,但用可预测或静态(或全零或其他)的东西替换 IV,这会导致所选对象的漏洞(已知?)明文攻击。
这是我正在谈论的事情的一个场景,以防它令人困惑。Alice (A) 和 Bob (B) 都生成良好的随机 96 位 nonce 材料(Am 和 Bm)并将它们附加到他们的 x.509 证书中。为了说明,我将使用小数字 Am=1234 和 Bm=4321。当没有 MITMed 时,每个人都会计算 Am⊕Bm = 5171。这将用作随机数。Eve 决定 MITM 他们打败 IV。她确保他们最终会得到常数 IV “6666”。当 A 向 B 发送 Am“1234”时,Eve ARP 欺骗 Bm 并将其替换为“2795”。当 B 将 Bm“4321”发送给 A 时,Eve 将其替换为“7896”。1234⊕7896 == 4312⊕2795 == 6666。
以下是我的想法/想法:
使用签名密钥 (ECDSA) 对 nonce 材料进行签名:在这一点上,我无法验证 GCM 本身之外的任何内容(即我没有使用 ECDSA 密钥或管理它们)。我想严格遵守 Suite B 算法。我知道我可以使用 GCM 验证明文(AEAD 的“AD”部分——带有关联数据的验证加密),但当然我还没有建立 IV……所以我不能用这个验证 IV 材料,可以我?对我来说,我似乎应该能够只使用 GCM 的对称密钥(我已经通过 ECDH 建立)来对此进行身份验证,因为它不需要加密,所以没有秘密——只有明文和 GCM MAC - 但我无法弄清楚如何在没有 BC 的 IV 的情况下初始化 AEADBlockCipher。“傻瓜”会不会很蠢 首先用全零 IV 初始化密码,正确的密钥,然后将 Nonce 处理为“关联数据”(未加密),最终确定缓冲区(附加 MAC),将其发送给对等方,然后重新初始化用真正的 IV 和相同的密钥加密?或者,我很确定我可以使用 ECDSA 签署随机数(如果我愿意,可能与 ECDH 公钥一起),但这需要分发也由服务器认证的 ECDSA 公钥,这增加了我想要的复杂性宁可避免(这也是我的第一个签约想法)
记录并禁止重复使用相同的 IV/Key 组合:IV 的重要之处在于它只与给定的密钥一起使用一次。因此,如果有人进行上述 MITM 攻击以反复用人为替换 IV,这个想法只会注意到并关闭连接。如果他们用派生出未使用 IV 的有效替代对替换它,攻击者将不会获得任何优势(对吗?)。在我的设计中,ECDH 对的私钥从未真正命中磁盘,因此在程序调用之间我将拥有所有新的对称密钥,因此这组密钥+IV 对可以很容易地保存在内存中,所以我真的很喜欢这种方法:- )
使用来自 ECDH 的秘密材料作为“面具”来制作秘密 IV:获取已建立的ECDH秘密材料(尚未传递给X9.63密钥生成器(BC中的ECDHKEKGenerator))。以某种方式从中获取 96 位 (Km),例如材料本身的前 96 位或材料的 SHA-1 摘要的前 96 位。Alice 和 Bob 生成随机的 96 位 nonce 材料(Am 和 Bm)。A 和 B 分别计算 Am⊕Km 和 Bm⊕Km,然后将它们的值发送给对方。一旦 A 有 Bm⊕Km,B 有 Am⊕Km,A 执行 Km⊕(Bm⊕Km) 得到 Bm,B 执行 Km⊕(Am⊕Km) 得到 Am。然后 A 和 B 都执行 Am⊕Bm,我们最终得到了 IV。如果它被篡改,A 和 B 将有不同的 IV,因为 Eve 不知道 Km,所以她不能精确地操纵它,对吧?这将导致 GCM 在交换第一条消息时检测到篡改,因此不会造成任何伤害。这种方法有什么问题?
很抱歉这个问题很长,请不要告诉我不要实现自己的协议,因为我这样做是为了了解作为 CS 学生的实现细节——而不是如何忽略它们。