首页 > 其他分享 >RSA加密

RSA加密

时间:2024-07-24 22:30:47浏览次数:8  
标签:加密 cout int void RSA while IsPrime Euler

前言

RSA算法是1978年\(R.Rivest,A.Shamir,L.Adleman\)三位科学家提出的一种用数论构造的、也是迄今为止理论上最为成熟完善的公钥密码体制,大多用于架构非对称加密

密钥的产生:

  • 选取两个保密的大素数\(p\)和\(q\)。
  • 计算\(n=p \times q,\phi (n)=(p-1)(q-1)\),其中\(\phi (n)\)是\(n\)的欧拉函数值
  • 选取一个整数\(e\),满足\(1<e<\phi (n)\) ,并且\(\gcd (\phi (n),e)=1\)
  • 计算\(d\),满足\(d \times e \equiv 1 \mod \phi (n)\),即\(d\)是\(e\)在\(\mod \phi(n)\)下的乘法逆元,因\(e\)与\(\phi(n)\)互素,由模运算可知,他的乘法逆元一定存在
  • 以\({d,n}\)为公开钥,\({d,n}\)为秘密钥

加密

  • 首先将明文比特串分组,使得每个分组对应的十进制数小于\(n\),即分组长度小于\(\log n\),然后对每个明文分组\(m\),作加密运算:
    \(c\equiv m^{e}\mod n\)

解密

  • 对密文分组的解密运算为:
    \(m \equiv c^{d} \mod n\)

实现

判断素数

判断素数
 int IsPrime(int n)
{
	 int temp=(int)sqrt(n);
	for(int i=2;i<=temp;i++)
	{
		if(n%i==0) 
		  return 0;//n不是素数的话返回0
	}
	return 1;//n是素数的话返回1
}

选取素数

两个素数p,q是手动输入的。
p,q应满足:p为素数,q为素数,p,q互不相等

计算n和n的欧拉函数

计算n和n的欧拉函数值
void N(int p,int qint &n,int &Euler_n)
{
	n=p*q;
	Euler_n=(p-1)*(q-1);
}

GCD

求两个数的最大公约数
int GreatestCommonDivisor(int a,int b) 
{
	int t;
	if(a<b) 
	{
		// 交换两个数,使大数放在a的位置上。
		t=a;
		a=b;
		b=t;
	}
	while(b!=0)
	{
		// 利用辗转相除法,直到b为0为止。
		t=a%b;
		a=b;
		b=t;
	}
	return a;
}

求e

选取e
void E(int Euler_n,int &e)
{
	e=rand()%(Euler_n-1)+1; //e取值是1<e<Euler_n  即 [2,Euler_n]范围内的随机数
	do  // gcd(e,Euler_n)=1  ,e与Euler_n互素,最大公约数=1
	{
	e=rand()%(Euler_n-1)+1; //e取值是1<e<Euler_n  即 [2,Euler_n]范围内的随机数
	} 
	while(GreatestCommonDivisor(Euler_n,e)!=1);//当e与Euler_n最大公约数!=1时,循环不断地刷新e的值
}

求逆元d

求逆元d
void D(int e,int Euler_n ,int &d)
{
	int Sign_of_Inverse_Element=0;//判断是否求出逆元的标志:Sign_of_Inverse_Element。当Sign_of_Inverse_Element=1,则求出了逆元
	do
	{
		for(int i=1;i<Euler_n;i++)
		{
			if((i*e)%Euler_n==1)
			{
				Sign_of_Inverse_Element=1; //Sign_of_Inverse_Element=1时表面求出了逆元d
				d=i;
			}
		}
	} 
	while(Sign_of_Inverse_Element!=1);
}

对明文m的加密

对于明文m的加密
void E_m(int m,int e,int n,int &c)
{
	int product=1;//product表示m自身不断相乘的积  
	for(int i=1;i<=e;i++)//用e来控制m的指数
	{ 
		product=(product*m)%n;   
	}//注意不要忘记%n  
	c=product;
}

对密文c的解密

对密文c的解密
void D_c(int c,int d,int n,int& After_m)
{
	int product=1;//product表示c自身不断相乘的积
	for(int i=1;i<=d;i++)//用d来控制c的指数
	{
		product=(product*c)%n;
	}//注意不要忘记%n
	After_m=product;
}

整体代码

整体代码
#include<iostream>
using namespace std;
#define Size 10//明文串大小

//判断素数
 int IsPrime(int n)
{
	 int temp = (int)sqrt(n);
	for (int i = 2; i <= temp; i++)
	{
		if (n % i == 0) return 0;//n不是素数的话返回0
	}
	return 1;//n是素数的话返回1
}

//选取两个素数
void InputPrime(int &p, int &q)
{
	int P, Q;
	cout << "请输入两个不相等的大素数: p,q" << endl;
	cin >> P >> Q;
	
	
		do
		{  
		/*if(P == Q)
			{
				cout << "p,q不能相等,请重新输入两个大素数: p, q" << endl;
				cin >> P >> Q;
			} 

			if(IsPrime(P) != 1)
			{
				cout << P<<"不满足是素数,请重新输入大素数: p" << endl;
				cin >> P;
			} 

			if(IsPrime(Q) != 1)
			{
				cout << Q<< "不满足是素数,请重新输入大素数: q" << endl;
				cin >> Q;
			} 
			*/
		/*	do 
			{
				cout << "p,q不能相等,请重新输入两个大素数: p, q" << endl;
				cin >> P >> Q;
			} while (P == Q);

			do 
			{
				cout << P << "不满足是素数,请重新输入大素数: p" << endl;
				cin >> P;
			} while (IsPrime(P) != 1);

			do 
			{
				cout << Q << "不满足是素数,请重新输入大素数: q" << endl;
				cin >> Q;
			} while (IsPrime(Q) != 1);
			*/

			while (IsPrime(Q) != 1)
			{
				cout << Q << "不满足是素数,请重新输入大素数: q" << endl;
				cin >> Q;
			}

			while (IsPrime(P) != 1)
			{
				cout << P << "不满足是素数,请重新输入大素数: p" << endl;
				cin >> P;
			}

			while(P==Q)
			{
				cout << "p,q不能相等,请重新输入两个大素数: p, q" << endl;
				cin >> P >> Q;	
			}


		} while (IsPrime(P) !=1||IsPrime(Q)!=1||Q==P);	
	
	p = P;
	q = Q;
	
}

//计算n和n的欧拉函数值
void N(int p , int q, int &n,int &Euler_n)
{
	n = p * q;
	Euler_n = (p - 1) * (q - 1);
}

//求两个数的最大公约数
int GreatestCommonDivisor(int a, int b) 
{
	int t;
	if (a < b) 
	{
		// 交换两个数,使大数放在a的位置上。
		t = a;
		a = b;
		b = t;
	}
	while (b != 0)
	{
		// 利用辗转相除法,直到b为0为止。
		t = a % b;
		a = b;
		b = t;
	}
	return a;
}

//选取e
void E(int Euler_n,int &e)
{
	e = rand() % (Euler_n - 1) + 1; //e取值是1<e<Euler_n  即 [2,Euler_n]范围内的随机数
	do  // gcd(e,Euler_n)=1  ,e与Euler_n互素,最大公约数=1
	{
	e = rand() % (Euler_n - 1) + 1; //e取值是1<e<Euler_n  即 [2,Euler_n]范围内的随机数
	} while (GreatestCommonDivisor(Euler_n , e)!=1);//当e与Euler_n最大公约数!=1时,循环不断地刷新e的值
}

//求逆元d
void D(int e,int Euler_n ,int &d)
{
	int Sign_of_Inverse_Element=0;//判断是否求出逆元的标志:Sign_of_Inverse_Element。当Sign_of_Inverse_Element=1,则求出了逆元
	do
	{
		for (int i = 1; i <Euler_n; i++)
		{
			if ((i * e) % Euler_n == 1)
			{
				Sign_of_Inverse_Element = 1; //Sign_of_Inverse_Element=1时表面求出了逆元d
				d = i;
			}
		}
	} while (Sign_of_Inverse_Element !=1);

}

//对于明文m的加密   (这里认为m是由输入字符转成的二进制的十进制值)
void E_m(int m,  int e,int n, int &c  )
{
	   int product = 1;//product表示m自身不断相乘的积  
	   for (int i = 1; i <=e; ++i)//用e来控制m的指数
		{ product = (product *m)%n;   }//注意不要忘记%n  
	   c = product;
}

//对密文c的解密
void D_c(int c, int d, int n, int& After_m)
{
	int product = 1;//product表示c自身不断相乘的积
	for (int i = 1; i <= d; ++i)//用d来控制c的指数
	{product = (product * c) %n;}//注意不要忘记%n
	After_m= product;
}



//Bob想要收到别人的消息就要先制作公钥和私钥
void Bob_Make_PublicKey_And_PrivateKey(int &p , int &q, int& n,  int& e,int& d)
{
	int p1, q1, n1, Euler_n1, e1, d1;
	//Bob制作公钥的过程
	InputPrime(p1, q1);//选取两个素数
	p = p1;
	q = q1;

	N(p1, q1, n1, Euler_n1); //计算n和  n的欧拉函数值Euler_n
	n = n1;

	E(Euler_n1, e1);//选取e
	e = e1;
    cout << "Bob  (广播发送): “想给我发消息用这个公钥:{ e=" << e1 << ", n=" << n1 << "} ”" << endl;
	
	//Bob制作公钥的过程
	D(e1, Euler_n1, d1);//求逆元d
	d = d1;
	cout << "Bob  (自言自语): “只有我自己知道这个私钥:{ d=" << d1 << ", n=" << n1 << "} ”" << endl<<endl;
	
}

//Alice发送密文给Bob
void Alice_Send_Ciphertext_to_Bob(int n, int e, int C[])//全局变量C[]
{
	int M2[Size], C2[Size];
	//Alice对明文M[]加密
	cout << "Alice(自言自语):“我要发送给Bob的明文:";
	for (int i = 0; i < Size; i++)
	{
		M2[i] = rand() % n;//为了简要输入输出,这里就随机生成明文串的值
		E_m(M2[i], e, n, C2[i]);//加密
		C[i] = C2[i];
		cout << M2[i] << "  ";
		if (i == Size - 1) { cout <<" ”"<< endl; }
	}
	//Alice发送密文给Bob
	cout << "Alice(信道发送):“我要发送给Bob的密文:";
	for (int i = 0; i < Size; i++)
	{
		cout << C[i] << "  ";
		if (i == Size - 1) { cout << " ”" << endl<<endl; }
	}
}

//Bob解开密文
void Bob_Decode_Ciphertext_From_Alice( int n,  int d,int C[])全局变量C[]
{	
	
	int  After_M3[Size];
	//Bob收到的密文
	cout << "Bob  (信道接收):  “Alice给我的密文:   ";
	for (int i = 0; i < Size; i++)
	{
		cout << C[i] << "  ";
		if (i == Size - 1) { cout << " ”" << endl; }
	}

	//Bob解密后得到的明文
	cout << "Bob  (自言自语):  “解 密后的明文为:   ";
	for (int i = 0; i < Size; i++)
	{
		D_c(C[i], d, n, After_M3[i]);
		cout << After_M3[i] << "  ";
		if (i == Size - 1) { cout <<" ”"<< endl; }
	}
}


int main()
{
	int p, q ;
	int d;

    //攻击者只知道下面这些全局变量。这些全局变量是在广播或者信道中传播的
	int n, e;//公钥
	int C[Size];//密文串

	Bob_Make_PublicKey_And_PrivateKey(p, q, n, e, d);
	Alice_Send_Ciphertext_to_Bob(n, e, C);
	Bob_Decode_Ciphertext_From_Alice(n, d, C);

}

//这个main()函数也能运行,是一开始的版本,繁琐且不能体现Alice和Bob的交流过程
/*
int main()
{
	int p, q,n, Euler_n,e,d;
	int M[Size];//明文串
	int C[Size];//密文串
	int After_M[Size]; //解密后的明文
	
	InputPrime( p,  q);//选取两个素数
	N(p, q, n, Euler_n); //计算n和  n的欧拉函数值->Euler_n
	E(Euler_n,  e);//选取e
	D(e, Euler_n, d);//求逆元d

	//生成明文并加密
	cout << "明文为:";
	for (int i = 0; i < Size; i++)
	{
		M[i] = rand() % n;//为了简要输入输出,这里就随机生成明文串的值
		E_m(M[i], e, n, C[i]);//加密
		cout <<M[i]<< "  ";
		if (i == Size-1) { cout << endl; }
	}
	
	//	输出密文			 
	cout << "密文为:";
	for (int i = 0; i < Size; i++)
	{
		cout << C[i] << "  ";
		if (i == Size - 1) { cout << endl; }
	}
	
	//解密密文并输出解密后的明文
	cout << "解密后的明文为:";
	for (int i = 0; i < Size; i++)
	{
		D_c(C[i], d, n, After_M[i]);
		cout << After_M[i] << "  ";
		if (i == Size - 1) { cout << endl; }
	}	
}
*/



标签:加密,cout,int,void,RSA,while,IsPrime,Euler
From: https://www.cnblogs.com/MerlinForLee/p/18321906

相关文章

  • RSA已知n、e、密文c,求明文。
    题目文件fromCrypto.Util.numberimport*flag=b''m=bytes_to_long(flag)p=getPrime(128)q=getPrime(128)phi=(p-1)*(q-1)n=p*qe=65537c=pow(m,e,n)print(f"n:{n}")print(f"e:{e}")print(f"c:{c}")......
  • 密码学-RSA基础题解题脚本-Python
    importgmpy2#计算大整数模块importlibnumimportrsafromCrypto.PublicKeyimportRSA#安装时安装pycryptodome模块#已知:p,q,e,cdefknown_p_q_e_c():p=int(input('请输入一个素数p:'))q=int(input('请输入另一个素数q:'))e=int(input('请输入公钥e:'))......
  • Python实现RSA加密算法,让你的信息更加安全
    一、什么是编码    想要实现加密就必须要先了解什么是编码。    编码是信息从另一种形式或格式转换为另一种形式或格式的过程,解码则是编码的逆过程。字符编码(CharacterEncoding)是把字符集中的字符编码为指定集合中的某个对象,以便信息在计算机中传输。在密码......
  • 十款免费的文件加密软件:保护您的数据安全(资深人士强力推荐)
    “每次想到那些敏感数据可能面临的风险,我就头疼不已。”李明皱着眉头说。赵敏微微一笑,提议道:“别担心,我刚好知道几款非常出色的免费文件加密软件,能帮我们大大增强数据安全性。” 第一款:域智盾软件功能与优势:软件以其强大的加密技术和灵活的权限管理功能脱颖而出。它不......
  • 透明加密技术分享丨实测十款透明加密软件(宝藏收藏篇)
    小李:“最近公司数据安全问题频发,咱们得找些靠谱的透明加密软件来加强防护。”小王:“没错,我听说市面上有不少优秀的透明加密软件,咱们可以实测一下,挑出最适合咱们公司的。” 于是,他们开始了对十款透明加密软件的实测之旅,以下便是他们的发现与分享。第一款:域智盾基本信息:类......
  • 源代码加密软件,2024年企业常用的五款源代码加密软件推荐
    在当今高度数字化和竞争激烈的商业环境中,保护源代码的安全性对于企业来说至关重要。源代码不仅是企业的核心资产,也是创新和竞争优势的关键所在。一旦源代码泄露,可能导致知识产权的丧失、商业机密的暴露,甚至对企业的声誉造成不可挽回的损害。因此,选择一款可靠的源代码加密软件......
  • 源代码加密软件最新排名|企业源代码加密软件推荐
    随着企业数字化转型的加速,源代码作为软件开发的核心资产,其安全性变得尤为重要。源代码加密软件不仅能够保护企业的知识产权,还能防止商业机密的泄露,因此成为了众多企业关注的焦点。安秉源代码加密软件安秉源代码加密软件是一款专门设计用于保护企业源代码免遭泄露的专业加密......
  • 源代码加密软件是什么?源代码防泄密怎么做
    在软件开发领域,源代码是软件的心脏,其中包含的算法、业务逻辑和技术细节是软件公司的核心资产。一旦源代码泄露,可能会导致商业机密外泄、软件被恶意篡改或是直接被盗用,这不仅会造成经济损失,还可能损害企业的声誉。因此,对源代码进行加密是保护软件知识产权的重要手段之一。源代......
  • 使用 AES-GCM 分块加密文件
    我想编写一个生成器,以给定大小的块来加密文件并一一返回块。我还想验证有效负载,因此我为此选择了AES-GCM。为什么我要分块加密而不是一次性加密整个文件?我通过网络发送这些块,因此我不是加密整个(可能很大)文件,将其存储在其他地方,然后在进行网络传输时再次对其进行分块,而是加密......
  • 同花顺股票数据逆向:Cookie加密和Hook注入
    ......