RSA加密方式介绍
RSA(Rivest-Shamir-Adleman)是一种广泛使用的非对称加密算法,它利用一对密钥来进行加密和解密:公钥和私钥。RSA的安全性基于大整数分解的难度,即将一个大数分解成两个素数的乘积是非常困难的。
工作原理
RSA算法的核心流程包括密钥生成、加密和解密三个步骤。
-
密钥生成:
- 选择两个大素数 ppp 和 qqq,计算它们的乘积 n=p×qn = p \times qn=p×q。
- 计算 nnn 的欧拉函数 ϕ(n)=(p−1)(q−1)\phi(n) = (p-1)(q-1)ϕ(n)=(p−1)(q−1)。
- 选择一个公钥指数 eee(通常选取 65537,因为它是一个大质数,能有效避免计算中的漏洞)。
- 计算私钥指数 ddd,使得 d×e≡1 (mod ϕ(n))d \times e \equiv 1 \ (\text{mod} \ \phi(n))d×e≡1 (mod ϕ(n))。
-
加密:
- 明文 mmm 使用公钥加密:
c=me (mod n) c = m^e \ (\text{mod} \ n)c=me (mod n)
其中 ccc 是密文,mmm 是明文。
- 明文 mmm 使用公钥加密:
-
解密:
- 密文 ccc 使用私钥解密:
m=cd (mod n) m = c^d \ (\text{mod} \ n)m=cd (mod n)
其中 mmm 是明文,ccc 是密文。
- 密文 ccc 使用私钥解密:
C++ 实现代码
以下是 RSA 算法的简化实现,适用于教育和学习目的。为了简化,采用小数值和简单的加密,实际应用中会使用更大、更复杂的数值和优化过的算法。
代码实现
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <vector>
using namespace std;
// 计算 a^b % m
long long modExp(long long a, long long b, long long m) {
long long result = 1;
a = a % m;
while (b > 0) {
if (b % 2 == 1) {
result = (result * a) % m;
}
a = (a * a) % m;
b = b / 2;
}
return result;
}
// 求最大公约数 (Euclidean algorithm)
long long gcd(long long a, long long b) {
while (b != 0) {
long long temp = b;
b = a % b;
a = temp;
}
return a;
}
// 计算 a 的模反元素,满足 (a * x) % m = 1
long long modInverse(long long a, long long m) {
long long m0 = m, x0 = 0, x1 = 1;
if (m == 1) return 0;
while (a > 1) {
// q是商
long long q = a / m;
long long t = m;
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
if (x1 < 0) x1 += m0;
return x1;
}
// 生成两个大素数(用于RSA的p和q)——为了简化,使用较小素数
long long generatePrime() {
return rand() % 100 + 100; // 简单生成 100 到 200 之间的数作为素数
}
// RSA 密钥生成
void generateKeys(long long &e, long long &d, long long &n) {
long long p = generatePrime();
long long q = generatePrime();
n = p * q;
long long phi = (p - 1) * (q - 1);
// 选择 e,要求 1 < e < phi 且 gcd(e, phi) = 1
e = 3;
while (gcd(e, phi) != 1) {
e++;
}
// 计算 d,要求 e * d ≡ 1 (mod phi)
d = modInverse(e, phi);
}
// RSA 加密
long long encrypt(long long message, long long e, long long n) {
return modExp(message, e, n);
}
// RSA 解密
long long decrypt(long long ciphertext, long long d, long long n) {
return modExp(ciphertext, d, n);
}
int main() {
srand(time(0)); // 随机数种子
long long e, d, n;
generateKeys(e, d, n); // 生成RSA密钥对
cout << "Public Key: (e = " << e << ", n = " << n << ")\n";
cout << "Private Key: (d = " << d << ", n = " << n << ")\n";
long long message;
cout << "Enter message (a number): ";
cin >> message;
// 加密
long long ciphertext = encrypt(message, e, n);
cout << "Encrypted message: " << ciphertext << endl;
// 解密
long long decryptedMessage = decrypt(ciphertext, d, n);
cout << "Decrypted message: " << decryptedMessage << endl;
return 0;
}
代码解释
-
modExp
函数:- 用于计算 abmod ma^b \mod mabmodm,实现了快速幂算法,以高效处理大指数运算。
-
gcd
函数:- 使用欧几里得算法计算两个数的最大公约数,确保选择的公钥指数 eee 和 ϕ(n)\phi(n)ϕ(n) 互质。
-
modInverse
函数:- 计算 eee 的模反元素 ddd,满足 e×d≡1 (mod ϕ(n))e \times d \equiv 1 \ (\text{mod} \ \phi(n))e×d≡1 (mod ϕ(n)),这是RSA算法的关键。
-
generatePrime
函数:- 由于实际中生成大素数是很复杂的过程,这里使用简单的伪随机数生成方法产生两个小素数。
-
generateKeys
函数:- 用于生成公钥 (e,n)(e, n)(e,n) 和私钥 (d,n)(d, n)(d,n),通过选择两个素数 ppp 和 qqq,并计算它们的乘积 nnn,以及相应的欧拉函数值 ϕ(n)\phi(n)ϕ(n)。
-
加密和解密:
- 通过调用
encrypt
和decrypt
函数,分别使用公钥进行加密和使用私钥进行解密。
- 通过调用
运行示例
Public Key: (e = 3, n = 16499)
Private Key: (d = 10999, n = 16499)
Enter message (a number): 123
Encrypted message: 15778
Decrypted message: 123
注意事项
- 该实现为了简化使用了较小的素数,并且没有进行加密填充、素数测试等优化,因此它只适合用于学习和教育目的。
- 在实际应用中,RSA通常用于加密较小的数据(如对称密钥),而不是直接加密大文件。通常结合其他加密算法(如AES)来提升效率和安全性。