PS:如果你急于求成,只想在项目上直接应用RSA,那么请你直接跳转“四、具体实现”,随便找两个质数带入p、q套公式即可。
一、基本概念
1.RSA加密算法为非对称加密方法,即加密与解密使用不同的密钥。
2.加密密钥PK(公开),解密密钥SK(私有)。
3.加密算法E与解密算法D都公开
4.具体数学证明参考:算法学习笔记(3) RSA原理与证明_HarmoniaLeo的博客-CSDN博客
二、RSA加密
Hide: 密文
Expose: 明文
( E , N ) : 加密密钥
三、RSA解密
Hide: 密文
Expose: 明文
( D , N ) : 解密密钥
四、具体实现
(1)p 和 q : 随机获取两个质数
(2)N : N = p * q (质数相乘)
(3)L :
(4)E : 且 E与L互质,即gcd(E,L)==1
(5)D : 且 E * D mod L = 1
1. 获取两个质数p,q(线性筛法),目的是获取两个质数,你能获取到随便什么方法都行,不一定要用我这个方法。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10000100;
//primes数组用来存放质数
int primes[N], cnt;
//st[i], i为质数则为false否则为true
bool st[N];
void get_primes(int n)
{
for(int i = 2; i <= n; i++)
{
if(!st[i]) primes[cnt++] = i;
for(int j = 0; primes[j] <= n / i; j ++)
{
st[primes[j]*i] = true;
if(i % primes[j] == 0) break;
}
}
}
int main()
{
int n;
cin >> n;
get_primes(n);
cout << primes[--cnt] << endl;
return 0;
}
2. N的获取(直接乘算)
N = p * q即可
3. L的计算(套公式)
据公式L = (p-1)*(q-1)
4. E的计算
#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll x,ll y)//求最大公约数
{
int t;
if(x<y)
{
t=x;
x=y;
y=t;
}
return y==0 ? x : gcd(y , x%y);
}
int main()
{
ll p,q,L={L的值}#;//这一句是伪代码,别直接抄,给你看的,大括号里填具体的值
for(int E=2;E<=L;E++)
{
if(gcd(L,E)==1)cout<<E<<endl;
}
return 0;
}
5. D的计算
#include<iostream>
using namespace std;
typedef unsigned long long ll;
ll gcd(ll x,ll y)//求 x,y的最大公约数
{
ll t;
if(x<y)
{
t=x;
x=y;
y=t;
}
return y==0 ? x : gcd(y , x%y);
}
int main()
{
ll p,q,L={L的值}#,E={E的值}#;//伪代码给你看的,别直接抄,大括号里填具体的值
for(ll D=2;D<=L;D++)
{
if((E%L)*(D%L)%L==1)cout<<D<<endl;
}
return 0;
}
五、例子
1. 当p = 199,q = 211时 (随机取的质数)
2. L = (p - 1)*(q - 1) = 198 * 210 = 41580 (套公式)
3. N = p * q = 41989 (乘算)
4. 计算E:随机选取一个跟L互质的E (例 E = 17)
5. 当E = 17(上一步随机取的) ,L = 41580时 计算D,得出D = 22013
6. 将各参数代入样例代码中测试
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef unsigned long long ULL;
ULL N,L,E,D;
ULL RSAEnc(ULL num,ULL Z)//RSA加解密 num为数据 Z为指数项
{
ULL ans=1;
ULL i=Z;
while(i>0)
{
if(i&1)
{
ans=((ans%N)*(num%N))%N;
}
num=((num%N)*(num%N))%N;
i=i>>1;
}
return ans%N;
}
int main()
{
ULL num;
N=41989;E=17;D=22013;
cin>>num;
num=RSAEnc(num,E);
cout<<"加密后:"<<num<<endl;
num=RSAEnc(num,D);
cout<<"解密后:"<<num<<endl;
return 0;
}
结果检验为正确
本人是菜鸡,写这些主要是想记录一些自己的成长过程,如有写的不好的地方欢迎大佬指点指正!
参考: