【快速学】RSA数字签名(非对称加密算法)
RSA算法,如何使用
- 通过一个例子说明非对称加密的过程:
- 假设A,B两人进行公钥加密通信,A为信息发出者。
- B首先通过算法生成密钥对(包含公钥,私钥),之后将公钥发送给A,B保留私钥。
- A使用B发送来的公钥对信息进行加密,将密文发送给B,B利用自己的私钥对密文进行解密。
RSA算法生成密钥流程
- 给定两个质数p,q(p,q很大,不相等)
- 求出n=p*q
- 求出φ=(p-1)*(q-1)(不大于n,且与n互质的自然数)
- 找到一个符合条件的e(e<n 且 e与φ互质)
- 用辗转相除法求出x: 满足ex-1被φ整除(扩展欧几里得算法)
- 得到公钥(n, e),私钥(n, φ)
- 对信息A加密后生成R:R = Ae mod n
- 对信息R解密后生成A:A = Rx mod n
RSA算法程序
/*
RSA加密算法
*/
#include<iostream>
#include<cstring>
using namespace std;
class RSA
{
private:
static const int MAX = 1e3;//常量
char PlaintText[MAX] = {}; //明文
int Plaint[MAX] = {}; //明文(数字)
char CipherText[MAX] = {}; //密文
int Cipher[MAX] = {}; //密文(数字)
int len;
//生成密钥需要的变量
int p, q;
int n;
int e, x = 0, phi, y = 0;
//判断一个数是否是质数
bool isPrime(int n)
{
if (n <= 1)
{
return false;
}
for (int i = 2; i <= n / 2; ++i)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
//求a,b的最大公因数
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
//扩展欧几里得算法ax+by=1
int exgcd(int a, int b, int &x, int &y)
{
if (b == 0)
{
x = 1;
y = 0;
return a; //到达递归边界开始向上一层返回
}
int r = exgcd(b, a % b, x, y);
int temp = y; //把x y变成上一层的
y = x - (a / b) * y;
x = temp;
return r; //得到a b的最大公因数
}
//求x的y次方(mod n))
int PowModN(int x, int y)
{
long long ret = 1;
if (x == 0)
return 0;
else
{
while (y--)
{
ret *= x;
ret = ret % n;
}
return ret;
}
}
//对数字A加密
int CodeOne(int A)
{
return PowModN(A, e);
}
//对数字R解密
int DeCodeOne(int R)
{
return PowModN(R, x);
}
public:
//生成密钥
bool calcKey()
{
cout << "==================生成密钥===================" << endl;
cout << "请输入p:";
cin >> p;
if (!isPrime(p))
{
cout << "p不是素数" << endl;
return false;
}
cout << "请输入q:";
cin >> q;
if (!isPrime(q))
{
cout << "q不是素数" << endl;
return false;
}
cout << "===============生成密钥中=================" << endl;
n = p * q;
phi = (p - 1) * (q - 1);
cout << "n=" << n << endl;
cout << "phi=" << phi << endl;
for (int i = 2; i < n; i++)//找到一个e,e与phi互质,并求出符合条件的x,y
{
if (gcd(i, phi) == 1)
{
e = i;
exgcd(e, phi, x, y); //扩展欧几里得算法,求x,y
if (x > 0)
{
cout << "e=" << e << endl;
printf("e=%d,x=%d,phi=%d,y=%d\n", e, x, phi, y);
cout << "公钥:(" << n << "," << e << ")" << endl;
cout << "私钥:(" << n << "," << x << ")" << endl;
break;
}
}
}
cout << "===============密钥生成完毕===============" << endl;
return true;
}
//对字符串加密
void Code()
{
cout << "请输入明文:" << endl;
cin >> PlaintText;
len = strlen(PlaintText);
for (int i = 0; i < len; i++)
{
Plaint[i] = PlaintText[i];
Cipher[i] = CodeOne(Plaint[i]);
CipherText[i] = Cipher[i];
}
}
//对字符串解密
void DeCode()
{
// cout << "请输入密文:" << endl;
// cin>>CipherText;
for (int i = 0; i < len; i++)
{
Plaint[i] = DeCodeOne(Cipher[i]);
PlaintText[i] = Plaint[i];
}
}
//输出明文
void PrintPlaintText()
{
cout << PlaintText << endl;
}
//输出密文
void PrintCipherText()
{
cout << CipherText << endl;
}
//输出明文(数字)
void PrintPlaint()
{
for (int i = 0; i < len; i++)
{
cout << Plaint[i] << " ";
}
cout << endl;
}
//输出密文(数字)
void PrintCipher()
{
for (int i = 0; i < len; i++)
{
cout << Cipher[i] << " ";
}
cout << endl;
}
};
int main()
{
RSA r;
while (r.calcKey()) //生成密钥成功,才加密解密
{
r.Code();//加密
cout << " 明文:";
r.PrintPlaintText();
cout << "明文(数字):";
r.PrintPlaint();
cout << "加密后\n密文(数字):";
r.PrintCipher();
cout << " 密文:";
r.PrintCipherText();
r.DeCode();//解密
cout << "对上面密文解密后\n明文(数字):";
r.PrintPlaint();
cout << " 明文:";
r.PrintPlaintText();
}
return 0;
}
参考资料
https://www.bilibili.com/video/BV1sZ4y1H7WC
https://blog.csdn.net/destiny1507/article/details/81750874
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】