Diffie Hellman 及其必要性

  • mabeloza
  • 发布于 2022-12-01 20:31
  • 阅读 66

本文回顾了Diffie-Hellman密钥交换方法,并介绍了其在加密通信中的应用。

Diffie Hellman 以及为什么需要它

关于 Diffie Hellman 和 Signal 的 Diffie Hellman 实现(棘轮协议)的回顾。

Diffie Hellman 是一种端到端加密的密钥交换方法,它允许双方安全地通信,通过给予每一方足够的信息来获得相同的秘密,而无需共享该秘密。由 Ralph Merkle、Whitfield Diffie 和 Martin Hellman 于 1976 年开发,并由英国信号情报机构发现。

一些使用 Diffie Hellman 来增强安全性的协议包括:

  • SSH (安全外壳)
  • TLS (传输层安全)
  • SSL (安全套接字层)
  • PKI (公钥基础设施)
  • IKE (互联网密钥交换)
  • IPSec (互联网协议安全)
  • Signal——用于 WhatsApp、Facebook Messenger、Line 和 Signal 等消息应用程序
  • ZKP (零知识证明)

它是如何工作的?

整个想法是双方同意使用拼图的某些部分,使用这些部分以及只有他们知道的秘密来解决拼图的一部分,然后他们分享已解决的部分以获得共享的秘密。

  1. 选择共享部分: 双方,Alice 和 Bob,随机同意一个大的(至少 2048 位长)素数模数 p,以及 p 的本原根 g
  2. 密钥生成: Alice 选择一个秘密整数 a,并使用约定的参数来解决拼图的一部分 (g^a mod p = A)
  3. 密钥生成: Bob 做与 Alice 相同的事情,选择一个秘密整数 b,并使用约定的参数来解决拼图的一部分 (g^b mod p = B)
  4. 共享密钥: 现在双方都解决了他们的部分拼图,他们分享他们的答案,Alice 与 Bob 分享 A,反之亦然
  5. 计算密钥: Alice 获得 Bob 解决的部分 B,以及她的秘密整数 a,并求解共享秘密 (B^a mod p = S)
  6. 计算密钥: Bob 获得 Alice 解决的部分 A,以及他的秘密 b,并求解共享秘密 (A^b mod p = S)

瞧!现在双方都有了共享的秘密!

Diffie Hellman 的类型

传统的 Diffie Hellman 不再是一种安全的选择,因此在应用程序中,我们使用 Diffie Hellman 的不同变体,它们是:

  • 静态 Diffie Hellman: 使用证书来验证服务器。证书是静态的,不会每次都更改。
  • 临时 Diffie Hellman (DHE): 每次使用临时密钥进行身份验证。DHE 帮助我们实现完全正向保密 (PFS),因为公钥是临时的,服务器长期签名密钥的泄露不会危及过去会话的隐私。
  • 椭圆曲线临时 Diffie Hellman (ECDHE): 这与 DHE 的概念相同,但它使用椭圆曲线密钥对。下图是一个椭圆曲线 (y² = x³ - 2x + 2);公钥和私钥是从曲线上的不同点导出的。

完全正向保密

为每个事务创建唯一的密钥,因此即使黑客获得了密钥,他们也只能从单个事务中获取信息,而无法查看过去的信息。

以下是关于 PFS 重要性的有用资源:

完全正向保密 - 为什么你应该使用它 - KeyCDN

为什么使用它?

目前,RSA 和 Diffie Hellman (DH) 是互联网上最流行的加密算法。RSA 依赖于“因式分解问题”,而 DH 依赖于“离散对数问题”。一种加密算法并不比另一种更好;它们只是解决加密的不同方法,并且根据用例是有益的。

在 RSA 中,用户发布一个公钥,另一方使用该公钥来加密他们的消息。当他们将其发回时,用户可以使用他们的私钥解密消息。如果你想进一步深入了解 RSA,请查看下面的文章:

什么是 RSA 加密以及它是如何工作的?

有人会使用 Diffie Hellman 而不是 RSA,因为它的完全正向保密 (PFS) 功能。

使用 Diffie Hellman 的缺点 & Logjam 攻击

使用 Diffie Hellman 的一些缺点是:

  • 只能用于对称密钥交换
  • 不能用于签署数字签名,必须与 DSS(数字签名标准)结合使用才能验证身份并检查数据完整性
  • 容易受到中间人攻击,因为它不处理身份验证(需要在使用 DH 的任何系统之上添加身份验证层)

通过使用数字域筛选算法解决大多数离散对数问题,Logjam 攻击成为可能。整个想法是他们可以预先计算 G,因为大多数互联网流量都使用 1024 位或更小的组。一旦他们事先弄清楚了这一点,他们只需要担心解决特定的对数即可。

作者需要数千个 CPU 核心一周才能预先计算单个 512 位素数的数据以执行此攻击。预先计算 1024 位素数大约需要 1 亿美元。

建议使用椭圆曲线 Diffie Hellman 和至少 2048 位来防止 logjam 攻击。使用至少 2048 位会使求解难度比 1024 位素数高 10⁹ 倍。

请查看下面的白皮书,了解有关 Logjam 攻击的更多详细信息:

弱 Diffie-Hellman 和 Logjam 攻击

如何开始使用 Diffie Hellman?

好消息是有许多经过验证的库已经支持 Diffie Hellman。经验法则是“永远不要编写你自己的加密实现!”

NodeJS Crypto 库

如果你是 NodeJS 开发人员,则可以使用 Crypto 库。以下是指向文档的链接:

Crypto

以下是使用 Crypto 库实现 Diffie Hellman 的一个简单示例:

import assert from 'assert';

const {
  createDiffieHellman
} = await import('crypto');

// Generate Alice's keys...
// 生成 Alice 的密钥...
const alice = createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
// 生成 Bob 的密钥...
const bob = createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
// 交换并生成密钥...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));

由于 ECDH(椭圆曲线 Diffie Hellman)更受欢迎,因此这里有一个使用 Crypto 库实现 ECHD 的示例:

import assert from 'assert';

const {
  createECDH
} = await import('crypto');

// Generate Alice's keys...
// 生成 Alice 的密钥...
const alice = createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Generate Bob's keys...
// 生成 Bob 的密钥...
const bob = createECDH('secp521r1');
const bobKey = bob.generateKeys();

// Exchange and generate the secret...
// 交换并生成密钥...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

assert.strictEqual(aliceSecret.toString('hex'), bobSecret.toString('hex'));
// OK

Signal -> 双棘轮

Diffie Hellman 更复杂的实现是 Signal 的协议。双棘轮是大多数端到端加密消息应用程序(如 Signal 和 WhatsApp)中使用的实现。

该协议应该在密码学上模拟棘轮工具的功能(只能向前移动),同时使用以下功能:

  • KDF(密钥派生函数)链
  • X3DH(扩展三重 Diffie-Hellman)

棘轮技术来自这样的概念:你不能从后面的状态往回工作到之前的状态并解密过去的消息。双重来自于我们使用 KDF(密钥派生函数)链和 X3DH(扩展三重 Diffie Hellman)进行棘轮的事实。

KDF (密钥派生函数) 链

KDF 是一种加密哈希函数,它使用 HMAC 和 HKDF 哈希。它的功能类似于哈希,但它们是一种加密原语。

当 KDF 的一部分输出用作输出密钥,而另一部分用于替换 KDF 密钥时,我们使用术语 KDF 链,然后可以将其与另一个输入一起使用。

下图表示一个 KDF 链处理三个输入并生成三个输出密钥。

在消息传递场景中,第一条消息需要加密,因此它会通过 KDF 函数并生成一个 KDF 密钥和一个输出密钥。KDF 密钥是下一层的输入密钥,输出密钥加密第一条消息。第二条消息进来并且需要加密;发生相同的过程,但是输入密钥来自先前产生的 KDF 密钥,并且输出密钥对于以下消息是新的。

这样做的好处是你具有前向保密,如果密钥被破解,则无法解密过去的消息。它不提供的是未来保密,如果密钥被破解,那么你可以找出链中更下游的密钥。这就是 Diffie Hellman 棘轮发挥作用的地方,它提供了一种自修复特性,可以重置发送和接收 KDF 链。

回到消息传递场景,信使上的每个朋友都有 3 个棘轮,2 个 KDF 棘轮用于发送和接收消息,1 个用于重置消息。Alice 的发送棘轮必须始终与 Bob 的接收棘轮同步,这样他才能加密 Alice 的消息。现在和以后,或者可能在每条消息之后,我们必须重置 KDF 链,这样如果有人破解了 Alice 或 Bob 链中的一个密钥,我们可以保护他们免受未来被破解的其他消息的影响。

X3DH(扩展三重 Diffie Hellman)

X3DH 提供前向保密和密码学上的可否认性。它专为一方离线且需要保存到服务器的异步设置而设计。

X3DH 专为异步设置而设计,在这种设置中,一个用户(“Bob”)处于离线状态,但已将一些信息发布到服务器。 另一个用户(“Alice”)想要使用该信息向 Bob 发送加密数据,并建立用于未来通信的共享密钥。

X3DH 在高级别上执行以下步骤:

  1. Bob 将他的身份密钥和预密钥发布到服务器。
  2. Alice 从服务器获取一个“预密钥包”,并使用它向 Bob 发送初始消息。
  3. Bob 接收并处理 Alice 的初始消息。

查看 Signal 的官方文档 x3DH:

规范 >> X3DH 密钥协商协议

观看下面的视频,了解有关 X3DH 的简单解释:

视频最初在 https://asecuritysite.com/encryption/go_x3dh 上找到

以下是关于双棘轮协议内部运作的官方文档:

规范 >> 双棘轮算法

以下是双棘轮协议的 java 实现的官方 GitHub:

GitHub - signalapp/libsignal-protocol-java: 用于 Java/Android 的 Signal 协议库

结论

Diffie Hellman 已经存在超过 50 年了,但即使这么多年过去了,它在当今世界仍然非常流行。 即使今天没有人使用原始的 Diffie Hellman 实现,许多协议都是从 Diffie Hellman 派生的,并在我们每天使用的工具中使用,例如 WhatsApp、Signal 或 TLS 3.0。

想开始交易吗? 试试 加密货币交易机器人跟单交易

  • 原文链接: medium.com/insatiablemin...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
mabeloza
mabeloza
江湖只有他的大名,没有他的介绍。