学习物联网安全,让自己实现以下非对称加密算法RSA算法
根据原理进行Coding的时候发现由于太长时间不进行Coding,所以很是手生
于是万能的百度起来,但是发现网络上面的代码过于复杂,不太适合强行Coding,尤其是对于我这种懒得逐句理解的人来说
因为根据原理简单的Coding了一下,能够简单的实现RSP加解密
当然中间有一点内存空间不对称导致的乱码问题,,,,这都是小问题,能看就行
当然我也会把网上大神写的Code粘在后面
供大家参考
/*
RSA非对称加密算法
公钥-私钥对进行加解密
准备:明文M,公钥PU={e, n},私钥PR={d, n}
准备两个非常大的素数p和q,乘积为 n = p*q, f(n) = (p-1)*(q-1)
找出一个与互f(n)为质数的自然数e,1<e<f(n)
计算d, d = 1/e mod f(n)
最终得到公钥PU = {e, n}, 私钥PR = {d, n}
加密过程为 C = M^e mod n
解密过程为 M = C^d mod n
*/
/*
****************程序流程图*********************
开始
|
随机获取两个素数p与q
|
找出与f(n)互为质数的自然数e
|
计算获得d
|
PU={e, n},私钥={d, n}
|
RSA加密
|
RSA解密
*/
#include <iostream>
#include<math.h>
#include<ctime>
#include<cstdlib>
#include <string>
#include<string.h>
using namespace std;
//将num转换为i二进制储存在bin_num中
int BinaryTransform(int num, int *bin_num){
int i = 0;
int mod = 0;
while (num != 0)
{
mod = num%2;
bin_num[i++] = mod;
num >> 1;
}
return i;//返回二进制的位数
}
//辗转相除法求最大公因数
int Gcd(int a, int b){
if(b == 0)
return true;
return Gcd(b, a%b);
}
//获取n的互质数 e ,即另外一个数与n的最大公因数为1
int Gete(int n)
{
int another = n;//根据RSP算法的要求,e越大,加密效果越好
int flag = 1;
while (flag)
{
if(Gcd(n, ++another) == 1){
flag = 0;
}
}
return another;
}
//获取d, d与e关于f(n)同余
int Getd(int e, int n){
return (1/e % n);
}
int Getpq()
{
srand((unsigned)time(NULL));
return (10 + rand()%100);//生成一个10-100的随机数
}
int p, q, n, f, d, e;
void Init_RSA(){
//生成p, q, f(n), d, e
p = Getpq();
q = Getpq();
n = p*q;
f = (--p)*(--q);
d = Getpq();
e = Gete(d);
cout<< "p = " << p << endl
<< "q = " << q << endl
<< "n = " << n << endl
<< "f(n) =" << f <<endl
<< "d = " << d << endl
<< "e = " << e <<endl
<< "PU = {" << e << ", " << n <<"}" << endl
<< "PR = {" << d << ", " << n <<"}" << endl;
}
int GetPow(int x, int y)
{
while(y--){
x *= x;
}
return x;
}
string text; //加密内容
int Plaintext[100]; //明文
long long Ciphertext[1000]; //密文
//解密 m = c^d(mod n)
void GetPlaintext(int Ciphertext[], int num, int d, int n)
{
char sp[3];
char *res;
int i = 0;
while (num--)
{
int low = GetPow(*Ciphertext, n) % n;//将明文的每一位都进行加密
sprintf(sp, "%02d", low);//格式化为两位
strcat(res, sp);//拼接起来
}
cout << Ciphertext <<"加密完成, 结果为:" << res << endl;
*Ciphertext = {0};
}
//解密
void GetCiphertext(int *Plaintext, int num, int d, int n)
{
char sp[3];
char *res;
int i = 0;
while (num--)
{
int low = GetPow(Plaintext[i], n) % n; //将明文的每一位都进行加密
sprintf(sp, "%02d", low); //格式化为两位
strcat(res, sp); //拼接起来
}
cout << Plaintext << "解密完成, 结果为:" << res <<endl;
*Plaintext = {0};
}
int main(int argc, char const *argv[])
{
int text[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
if (text != NULL)
{
Init_RSA();
GetPlaintext(text, sizeof(text) / sizeof(text[0]), d, n);
system("pause");
}
return 0;
}
//另一种方式
#include<bits/stdc++.h>
using namespace std;
int Euler(int n)//欧拉函数 求1到n中有多少个整数与n互质
{
int rs=1;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
rs*=(i-1);
n/=i;
while(n%i==0)
{
rs*=(i-1);
n/=i;
}
}
}
if(n>1)
rs*=(n-1);
return rs;
}
int gcd(int a,int b)//求a,b的最大公约数
{
if(b==0)
return a;
return gcd(b,a%b);
}
int check(int n)//判断n是不是素数
{
if(n==1)
return 0;
if(n==2)
return 1;
for(int i=3;i*i<=n;i=i+2)
{
if(n%i==0)
return 0;
}
return 1;
}
int gnerating_primes(int n)//产生小于等于n的第一个素数
{
if(n%2==0)
n--;
for(int i=n;i>1;i=i-2)
{
if(check(i)==1)
return i;
}
return -1;//表示没有小于等于n的素数
}
int multiplicative_inverse_element(int a,int r)//求a对于r的乘法逆元
{
int rs=1;
if(check(r)==1)//r是素数 采用费马小定理
{
for(int i=1;i<=r-2;i++)
rs*=a,rs%=r;
}else //r不是素数,采用欧拉定理的推论
{
int k=Euler(r)-1;
for(int i=1;i<=k;i++)
rs*=a,rs%=r;
}
return rs;
}
int get_pk(int w)
{
int pk=2;
for(pk=2;pk<w;pk++)
{
if(gcd(w,pk)==1)
return pk;
}
return pk;
}
int square_multiplication(int x,int c,int r)//平方乘算法,x的c次方%r
{
string str="";
while(c)
{
str=(char)(c%2+'0')+str;
c/=2;
}
int rs=x;
int l=str.length();
for(int i=1;i<l;i++)
{
if(str[i]=='0')
rs=((rs%r)*(rs%r))%r;
else
rs=(((rs%r)*(rs%r))%r*x)%r;
}
return rs;
}
int main()
{
int p=47;
int q=61;
int r=p*q;//公开模数
cout<<"r="<<r<<endl;
int w=Euler(r);//1到r中与r互质的数的个数
//求得公钥
int pk=get_pk(w);
//pk=167;
cout<<"公钥(pk,r):("<<pk<<","<<r<<")"<<endl;
//求得私钥
int sk=multiplicative_inverse_element(pk,w);
cout<<"私钥(sk,r):("<<sk<<","<<r<<")"<<endl;
int M=123456789;//明文
int K=3;//K位一组
int temp=1;
for(int k=1;k<=K;k++)
temp*=10;
cout<<"密文:";
for(int i=1;i<=K;i++)
{
cout<<square_multiplication(M%temp,pk,r)<<" ";
M/=temp;
}
cout<<endl;
return 0;
}
原文链接:https://blog.csdn.net/qq_39382769/article/details/88273253
//第三种方式
#include <iostream>
#include <cmath>
#include <cstring>
#include <ctime>
#include <cstdlib>
using namespace std;
int Plaintext[100];//明文
long long Ciphertext[100];//密文
int n, e = 0, d;
//二进制转换
int BianaryTransform(int num, int bin_num[])
{
int i = 0, mod = 0;
//转换为二进制,逆向暂存temp[]数组中
while(num != 0)
{
mod = num%2;
bin_num[i] = mod;
num = num/2;
i++;
}
//返回二进制数的位数
return i;
}
//反复平方求幂
long long Modular_Exonentiation(long long a, int b, int n)
{
int c = 0, bin_num[1000];
long long d = 1;
int k = BianaryTransform(b, bin_num)-1;
for(int i = k; i >= 0; i--)
{
c = 2*c;
d = (d*d)%n;
if(bin_num[i] == 1)
{
c = c + 1;
d = (d*a)%n;
}
}
return d;
}
//生成1000以内素数
int ProducePrimeNumber(int prime[])
{
int c = 0, vis[1001];
memset(vis, 0, sizeof(vis));
for(int i = 2; i <= 1000; i++)if(!vis[i])
{
prime[c++] = i;
for(int j = i*i; j <= 1000; j+=i)
vis[j] = 1;
}
return c;
}
//欧几里得扩展算法
int Exgcd(int m,int n,int &x)
{
int x1,y1,x0,y0, y;
x0=1; y0=0;
x1=0; y1=1;
x=0; y=1;
int r=m%n;
int q=(m-r)/n;
while(r)
{
x=x0-q*x1; y=y0-q*y1;
x0=x1; y0=y1;
x1=x; y1=y;
m=n; n=r; r=m%n;
q=(m-r)/n;
}
return n;
}
//RSA初始化
void RSA_Initialize()
{
//取出1000内素数保存在prime[]数组中
int prime[5000];
int count_Prime = ProducePrimeNumber(prime);
//随机取两个素数p,q
srand((unsigned)time(NULL));
int ranNum1 = rand()%count_Prime;
int ranNum2 = rand()%count_Prime;
int p = prime[ranNum1], q = prime[ranNum2];
n = p*q;
int On = (p-1)*(q-1);
//用欧几里德扩展算法求e,d
for(int j = 3; j < On; j+=1331)
{
int gcd = Exgcd(j, On, d);
if( gcd == 1 && d > 0)
{
e = j;
break;
}
}
}
//RSA加密
void RSA_Encrypt()
{
cout<<"Public Key (e, n) : e = "<<e<<" n = "<<n<<'\n';
cout<<"Private Key (d, n) : d = "<<d<<" n = "<<n<<'\n'<<'\n';
int i = 0;
for(i = 0; i < 100; i++)
Ciphertext[i] = Modular_Exonentiation(Plaintext[i], e, n);
cout<<"Use the public key (e, n) to encrypt:"<<'\n';
for(i = 0; i < 100; i++)
cout<<Ciphertext[i]<<" ";
cout<<'\n'<<'\n';
}
//RSA解密
void RSA_Decrypt()
{
int i = 0;
for(i = 0; i < 100; i++)
Ciphertext[i] = Modular_Exonentiation(Ciphertext[i], d, n);
cout<<"Use private key (d, n) to decrypt:"<<'\n';
for(i = 0; i < 100; i++)
cout<<Ciphertext[i]<<" ";
cout<<'\n'<<'\n';
}
//算法初始化
void Initialize()
{
int i;
srand((unsigned)time(NULL));
for(i = 0; i < 100; i++)
Plaintext[i] = rand()%1000;
cout<<"Generate 100 random numbers:"<<'\n';
for(i = 0; i < 100; i++)
cout<<Plaintext[i]<<" ";
cout<<'\n'<<'\n';
}
int main()
{
Initialize();
while(!e)
RSA_Initialize();
RSA_Encrypt();
RSA_Decrypt();
return 0;
}