- 密码学教程
- 密码学 - 首页
- 密码学 - 起源
- 密码学 - 历史
- 密码学 - 原理
- 密码学 - 应用
- 密码学 - 优点与缺点
- 密码学 - 现代
- 密码学 - 传统密码
- 密码学 - 加密的需求
- 密码学 - 双重强度加密
- 密码系统
- 密码系统
- 密码系统 - 组成部分
- 密码系统攻击
- 密码系统 - 彩虹表攻击
- 密码系统 - 字典攻击
- 密码系统 - 暴力攻击
- 密码系统 - 密码分析技术
- 密码学的类型
- 密码系统 - 类型
- 公钥加密
- 现代对称密钥加密
- 密码学哈希函数
- 密钥管理
- 密码系统 - 密钥生成
- 密码系统 - 密钥存储
- 密码系统 - 密钥分发
- 密码系统 - 密钥撤销
- 分组密码
- 密码系统 - 流密码
- 密码学 - 分组密码
- 密码学 - Feistel分组密码
- 分组密码的操作模式
- 分组密码的操作模式
- 电子密码本 (ECB) 模式
- 密码分组链接 (CBC) 模式
- 密码反馈 (CFB) 模式
- 输出反馈 (OFB) 模式
- 计数器 (CTR) 模式
- 经典密码
- 密码学 - 反向密码
- 密码学 - 凯撒密码
- 密码学 - ROT13算法
- 密码学 - 置换密码
- 密码学 - 加密置换密码
- 密码学 - 解密置换密码
- 密码学 - 乘法密码
- 密码学 - 仿射密码
- 密码学 - 简单替换密码
- 密码学 - 简单替换密码加密
- 密码学 - 简单替换密码解密
- 密码学 - 维吉尼亚密码
- 密码学 - 维吉尼亚密码实现
- 现代密码
- Base64编码与解码
- 密码学 - XOR加密
- 替换技术
- 密码学 - 单字母替换密码
- 密码学 - 单字母替换密码破解
- 密码学 - 多字母替换密码
- 密码学 - Playfair密码
- 密码学 - Hill密码
- 多字母替换密码
- 密码学 - 一次性密码本
- 一次性密码本的实现
- 密码学 - 置换技术
- 密码学 - 栅栏密码
- 密码学 - 列置换密码
- 密码学 -隐写术
- 对称算法
- 密码学 - 数据加密
- 密码学 - 加密算法
- 密码学 - 数据加密标准 (DES)
- 密码学 - 三重DES
- 密码学 - 双重DES
- 高级加密标准 (AES)
- 密码学 - AES结构
- 密码学 - AES变换函数
- 密码学 - 字节替换变换
- 密码学 - 行移位变换
- 密码学 - 列混淆变换
- 密码学 - 轮密钥加变换
- 密码学 - AES密钥扩展算法
- 密码学 - Blowfish算法
- 密码学 - SHA算法
- 密码学 - RC4算法
- 密码学 - Camellia加密算法
- 密码学 - ChaCha20加密算法
- 密码学 - CAST5加密算法
- 密码学 - SEED加密算法
- 密码学 - SM4加密算法
- IDEA - 国际数据加密算法
- 公钥(非对称)密码算法
- 密码学 - RSA算法
- 密码学 - RSA加密
- 密码学 - RSA解密
- 密码学 - 创建RSA密钥
- 密码学 - 破解RSA密码
- 密码学 - ECDSA算法
- 密码学 - DSA算法
- 密码学 - 迪菲-赫尔曼算法
- 密码学中的数据完整性
- 密码学中的数据完整性
- 消息认证
- 密码学数字签名
- 公钥基础设施 (PKI)
- 哈希算法
- MD5 (消息摘要算法5)
- SHA-1 (安全哈希算法1)
- SHA-256 (安全哈希算法256位)
- SHA-512 (安全哈希算法512位)
- SHA-3 (安全哈希算法3)
- 密码哈希
- Bcrypt哈希模块
- 现代密码学
- 量子密码学
- 后量子密码学
- 密码协议
- 密码学 - SSL/TLS协议
- 密码学 - SSH协议
- 密码学 - IPsec协议
- 密码学 - PGP协议
- 图像与文件加密
- 密码学 - 图像
- 密码学 - 文件
- 隐写术 - 图像
- 文件加密和解密
- 密码学 - 文件加密
- 密码学 - 文件解密
- 物联网中的密码学
- 物联网安全挑战、威胁和攻击
- 物联网安全的密码技术
- 物联网设备的通信协议
- 常用密码技术
- 自定义构建密码算法(混合密码学)
- 云密码学
- 量子密码学
- 密码学中的图像隐写术
- DNA密码学
- 密码学中的一次性密码 (OTP) 算法
- 区别
- 密码学 - MD5 vs SHA1
- 密码学 - RSA vs DSA
- 密码学 - RSA vs 迪菲-赫尔曼
- 密码学 vs 密码学
- 密码学 - 密码学 vs 密码分析
- 密码学 - 经典 vs 量子
- 密码学 vs 隐写术
- 密码学 vs 加密
- 密码学 vs 网络安全
- 密码学 - 流密码 vs 分组密码
- 密码学 - AES vs DES密码
- 密码学 - 对称 vs 非对称
- 密码学有用资源
- 密码学 - 快速指南
- 密码学 - 讨论
密码学 - 迪菲-赫尔曼算法
迪菲-赫尔曼密钥交换是一种数字加密方法,两个不同的参与方可以在公共信道上安全地交换加密密钥,而无需通过互联网发送他们的通信。双方都使用对称加密来加密和解密他们的消息。
惠特菲尔德·迪菲和马丁·赫尔曼于1976年发表了它,这是最早的实用公钥密码学案例之一。
迪菲-赫尔曼密钥交换将数字提高到特定的幂以生成解密密钥。密钥的组成部分从未直接传输,这使得潜在的代码破解者在数学上无法完成任务。该方法在密钥交换过程中不共享任何信息。即使事先彼此不了解,双方也可以协作生成密钥。
迪菲-赫尔曼的历史
惠特菲尔德·迪菲和马丁·赫尔曼于1976年开发了迪菲-赫尔曼算法,它为公钥密码学铺平了道路,并极大地提高了数字安全性。它是为解决在不安全信道上安全密钥交换而开发的,取代了对称密钥分发方法,并为SSL/TLS等安全通信协议奠定了基础。
该算法对世界地缘政治产生了相当大的影响,例如在冷战后期用于确保北约国家之间的绝密通信。
迪菲-赫尔曼是如何工作的?
要使用迪菲-赫尔曼,两个最终用户Alice和Bob必须就正整数p和q达成一致,其中p是素数,q是p的生成元。生成元q是一个数字,当将其提高到小于p的正整数幂时,不会为任何两个这样的整数给出相同的结果。p的值可以很大,而q的值通常很小。
在Alice和Bob秘密决定了p和q之后,他们选择正整数私钥a和b。两者都小于素数模p。任何一方都不与任何人共享他们的私钥;理想情况下,他们记住这些数字,并且不将其写下或保存在任何地方。之后,Alice和Bob使用下面的算法根据他们的私钥计算公钥a*和b* −
a* = qa mod p b* = qb mod p
两个用户可以通过不安全的通信信道(例如互联网或公司的广域网)交换他们的公钥a*和b*。使用各自的私钥,每个用户都可以根据这些公钥生成一个数字x。Alice使用以下公式计算x −
x = (b*) mod p
Bob使用以下公式计算x:x = (a*)b mod p
上述两个公式中的任何一个都会给出x值的相同结果。但是,计算x所需的私钥a和b并没有通过公共信道发送。即使借助能够进行数百万次尝试的高效系统,潜在的黑客也几乎没有机会正确确定x,因为它的大小巨大且看似随机。因此,使用解密密钥x,两个用户理论上可以使用他们选择的任何加密技术在公共信道上进行私人对话。
分步指南
让我们以Alice和Bob这两个朋友的简单案例来描述迪菲-赫尔曼 −
选择素数和生成元
Bob和Alice已经决定了一个素数,p = 23。
此外,他们还同意一个生成元,g = 5。
选择私钥
Alice选择一个秘密数字,例如a = 6。
Bob选择一个秘密数字,例如b = 15。
确定公钥
Alice首先计算A = ga mod p,得到A = 56 mod 23,即8。
Bob使用公式B = gb mod p得到B = 515 mod 23,即19。
交换公钥
Alice向Bob提供她计算出的公钥A = 8。
Bob向Alice发送他计算出的公钥B = 19。
计算共享密钥
Alice使用Bob的公钥计算共享密钥 −
KA = Ba mod p −
KA = 196 mod 23,即2。
Bob使用Alice的公钥计算共享密钥 −
KB = Ab mod p −
KB = 815 mod 23,即2。
因此,Alice和Bob现在可以使用相同的共享密钥K = 2来加密他们的消息。
即使窃听者成功获取素数 p=23 和生成元 g=5,也很难推算出共享密钥。这是因为他们不知道爱丽丝或鲍勃的私钥。
Diffie-Hellman 算法实现
我们将使用 Python、Java 和 C++ 实现 Diffie-Hellman 算法。
Python 实现
下面的 Python 代码演示了 Diffie-Hellman 密钥交换算法,实现了爱丽丝和鲍勃之间的安全通信。
为了避免溢出错误,`calculate_power` 函数有效地计算了 ab mod P,其中 a、b 和 P 是大数。双方商定的重要参数(例如素数(prime)和生成元值(generator))被初始化。每一方选择其私钥(`private_key_bob` 和 `private_key_alice`),然后使用模幂运算计算其公钥。最终,在交换公钥后,爱丽丝和鲍勃分别计算共享密钥(`secret_key_alice` 和 `secret_key_bob`),从而实现安全通信。
以下是使用 Python 实现的 Diffie-Hellman 算法:
示例
def calculate_power(base, exponent, modulus): """Power function to return value of (base ^ exponent) mod modulus.""" if exponent == 1: return base else: return pow(base, exponent) % modulus # Driver code if __name__ == "__main__": prime = 23 generator = 5 private_key_alice = 6 private_key_bob = 15 # Generating public keys x = calculate_power(generator, private_key_alice, prime) y = calculate_power(generator, private_key_bob, prime) # Generating secret keys after the exchange of keys secret_key_alice = calculate_power(y, private_key_alice, prime) secret_key_bob = calculate_power(x, private_key_bob, prime) # Output print("Prime number (P):", prime) print("Generator value (G):", generator) print("Alice's private key (a):", private_key_alice) print("Bob's private key (b):", private_key_bob) print("Secret key for Alice:", secret_key_alice) print("Secret key for Bob:", secret_key_bob)
以下是上述示例的输出:
输入/输出
Prime number (P): 23 Generator value (G): 5 Alice's private key (a): 6 Bob's private key (b): 15 Secret key for Alice: 2 Secret key for Bob: 2
C++ 实现
这段代码使得爱丽丝和鲍勃能够安全地进行通信。该方法通过模幂运算有效地计算共享密钥,并兼容大整数。爱丽丝和鲍勃生成各自的私钥并计算对应的公钥。然后,每一方使用这些公钥以及自己的私钥分别计算共享密钥。
以下代码在 C++ 中实现了 Diffie-Hellman 密钥交换算法。
示例
#include <iostream> #include <cmath> using namespace std; // Function to calculate power modulo P long long int calculatePower(long long int base, long long int exponent, long long int modulus) { if (exponent == 1) return base; else return (((long long int)pow(base, exponent)) % modulus); } int main() { long long int prime, generator, secretAlice, secretBob, publicAlice, publicBob, secretKeyAlice, secretKeyBob; // Prime number and generator value initialization prime = 23; cout << "Prime number (P): " << prime << endl; generator = 5; cout << "Generator value (G): " << generator << endl; // Alice's private key initialization secretAlice = 6; cout << "Alice's private key (a): " << secretAlice << endl; // Calculate Alice's public key publicAlice = calculatePower(generator, secretAlice, prime); // Bob's private key initialization secretBob = 15; cout << "Bob's private key (b): " << secretBob << endl; // Calculate Bob's public key publicBob = calculatePower(generator, secretBob, prime); // Calculate secret keys for Alice and Bob secretKeyAlice = calculatePower(publicBob, secretAlice, prime); secretKeyBob = calculatePower(publicAlice, secretBob, prime); // Output secret keys cout << "Secret key for Alice: " << secretKeyAlice << endl; cout << "Secret key for Bob: " << secretKeyBob << endl; return 0; }
以下是上述示例的输出:
输入/输出
Prime number (P): 23 Generator value (G): 5 Alice's private key (a): 6 Bob's private key (b): 15 Secret key for Alice: 2 Secret key for Bob: 2
Java 实现
在这个实现中,我们使用了与 C++ 程序中相同的方法。但是,我们创建了一个名为 `DiffieHellman` 的类,其中包含 `calculatePower()` 函数和 `main()` 函数。Java 实现如下:
示例
public class DiffieHellman { // Power function to return value of a ^ b mod P private static long calculatePower(long base, long exponent, long modulus) { if (exponent == 1) return base; else return (((long) Math.pow(base, exponent)) % modulus); } // Driver code public static void main(String[] args) { long prime, generator, x, privateKeyAlice, y, privateKeyBob, secretKeyAlice, secretKeyBob; // Both parties agree upon the public keys generator and prime // A prime number prime is chosen prime = 23; System.out.println("Prime number (P): " + prime); // A primitive root for prime, generator is chosen generator = 5; System.out.println("Generator value (G): " + generator); // Alice chooses her private key privateKeyAlice privateKeyAlice = 6; System.out.println("Alice's private key (a): " + privateKeyAlice); // Gets the generated key x = calculatePower(generator, privateKeyAlice, prime); // Bob chooses his private key privateKeyBob privateKeyBob = 15; System.out.println("Bob's private key (b): " + privateKeyBob); // Gets the generated key y = calculatePower(generator, privateKeyBob, prime); // Generating the secret key after the exchange of keys secretKeyAlice = calculatePower(y, privateKeyAlice, prime); // Secret key for Alice secretKeyBob = calculatePower(x, privateKeyBob, prime); // Secret key for Bob System.out.println("Secret key for Alice: " + secretKeyAlice); System.out.println("Secret key for Bob: " + secretKeyBob); } }
以下是上述示例的输出:
输入/输出
Prime number (P): 23 Generator value (G): 5 Alice's private key (a): 6 Bob's private key (b): 15 Secret key for Alice: 2 Secret key for Bob: 2
应用/用途
Diffie-Hellman 密钥交换的目标是为对称密钥算法开发安全的密钥生成和共享通道。它常用于前向保密、加密和密码认证密钥协商。密码认证密钥协商可防止中间人攻击 (MitM)。前向保密过程通过为每个会话生成新的密钥对来防止密钥丢失。
Diffie-Hellman 密钥交换用于多种安全协议,包括传输层安全 (TLS)、安全外壳协议 (SSH) 和 IP 安全 (IPsec)。例如,在 IPsec 中,该加密机制用于生成和轮换密钥。
虽然 Diffie-Hellman 密钥交换可用于创建公钥和私钥,但 Rivest-Shamir-Adleman 算法(或 RSA 算法)也是另一种选择,因为它可以签名公钥证书。
Diffie-Hellman 密钥交换示例
Diffie-Hellman 密钥交换技术是一种加密技术。例如,爱丽丝和鲍勃可以使用它在开放的公共网络上交换敏感数据,同时保护自己免受黑客和窃听者的攻击。这个开放的公共网络可以在咖啡馆中找到。
爱丽丝和鲍勃私下选择秘密密钥,然后运行一个函数来生成公钥。共享的是结果,而不是函数本身。即使其他人可以访问所有相关的数字,也很难推断出这些数字来自哪个函数。
之后,爱丽丝和鲍勃使用从对方收到的结果、他们独特的秘密号码和初始素数值分别执行函数。然后,爱丽丝和鲍勃得到一个其他人无法知道的共享密钥。现在,鲍勃和爱丽丝可以安全地互相通信,而无需担心外部人士。
漏洞
基本版本的 Diffie-Hellman 的主要限制是缺乏身份验证。仅使用 Diffie-Hellman 的通信容易受到中间人攻击 (MitM)。Diffie-Hellman 应与公认的身份验证方法(如数字签名)结合使用,以验证公共通信介质上的用户身份。
Diffie-Hellman 密钥交换也容易受到 Logjam 攻击,特别是针对 TLS 协议。Logjam 攻击将 TLS 连接降低到 512 位加密,允许攻击者访问和修改通过连接传输的数据。如果正确实施,Diffie-Hellman 密钥交换仍然是安全的。例如,使用 2048 位密钥时,Logjam 攻击将失败。
优势/益处
- 它是一种有效的密钥交换和安全连接设置方法,无需事先准备。
- 它提供前向保密性,即使一个密钥被泄露,也能确保之前的对话安全。
- 无需传输安全的秘密密钥,降低了密钥在传输过程中被泄露的可能性。
- 此技术允许大量用户安全地进行交互,使其适用于大型应用程序。
劣势/局限性
- 需要安全的首次公钥交换以防止中间人攻击和窃听攻击。
- 容易受到拥有强大计算能力的对手的暴力破解攻击。
- 计算量很大,可能会影响性能,特别是对于大的素数。
- 缺乏身份验证,需要采取进一步措施来验证通信双方的身份。
Diffie-Hellman 和 RSA 的区别
差异如下表所示:
差异基础 | Diffie-Hellman | RSA |
---|---|---|
密钥功能 |
在此算法中,发送方和接收方使用相同的密钥。 |
RSA 广泛利用加密连接,因为它遵循加密技术。 |
密钥生成 |
双方都生成自己的密钥。 |
公钥和私钥都用于安全。 |
性能 |
它对于密钥交换效率高,但对于加密/解密较慢。 |
它对于加密/解密速度快,但对于密钥交换较慢。 |
密钥长度 |
通常需要更长的密钥长度才能达到相同的安全级别。 |
较短的密钥长度允许 Diffie-Hellman 提供与较长密钥相同的安全级别。 |
用途 |
它通常用于对称加密系统中的安全密钥交换。 |
它用于各种目的,通过加密和解密数据来确保安全。 |