【密码学2】公钥密码算法(RSA)

该文介绍了如何使用RSA算法进行公钥和私钥的生成,包括选取大素数p和q,计算乘积n和欧拉函数Φ(n),并实现公钥e和私钥d的选择。此外,还提供了基于Miller-Rabin素性测试的随机大素数生成方法。接着,文章详细阐述了加密和解密过程,以及相应的代码实现。实验结果显示了大素数生成、密钥对创建和RSA加密解密的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)实验要求:

1、编写程序构造一公钥密码算法(RSA)的密钥;
2、编写程序生成大素数;
3、编程实现一公钥密码算法。

(二)实验原理

1.首先是密钥对的生成:

(1)选取两个大素数p和q
(2)计算乘积n=p*q,Φ(n)=(p-1)(q-1),其中Φ(n)为n的欧拉函数
(3)随机选取整数e(1<e<Φ(n))作为公钥d,要求满足e与Φ(n)的最大公约数为1,即两者互素
(4)用Euclid扩展算法计算私钥d,已满足d * e ≡ 1 (mod Φ(n)),
即d ≡ e^(-1) (mod Φ(n))。则e与n是公钥,d是私钥
注意:e与n应公开,两个素数p和q不再需要,可销毁,但绝不可泄露。

2.加密过程:C=M^e mod N

3.解密过程:M=C^d mod N

(三)主要代码

1.生成大素数(生成大素数,素性检测)

因为没有想到如何实现生成并使用大素数,p,q只使用了1000以内随机生成的素数

(1)生成大素数

int ProducePrimeNumber(int prime[])//生成1000以内素数
{
	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;
}

(2)素性测试

bool Miller_Rabin(ll n) //Miller-Rabin素性测试算法
{
	ll r = 0;
	ll z = 0;
	ll m = 0;
	ll s = 0;
	m = n - 1;
	if (n < 2)
		return false;
	else if (n == 2)
		return true;
 
	while (m % 2 == 0) {
		m /= 2;
		s = s + 1;
	}
	srand(time(NULL));
	ll b = rand() % (n - 2) + 2;
	/*for(int i = 0;i < m - 1;i++)
		z1 = b*b;
	z1 = ((z1 % n) + n)% n;*/
	z = Power_mul(b, m, 1, n);
	if (z == 1 || z == n - 1)
		return true;
	else
	{
		while (1) {
			if (r == (s - 1))
				return false;
			else
			{
				r = r + 1;
				z = Power_mul(z, 2, 1, n);
				if (z == (n - 1))
					return true;
			}
		}
	}
}
 
void MR()
{
	ll N;
	bool result;
	cout << "请输入N:";
	cin >> N;
	result = Miller_Rabin(N);
	if (result)
		cout << N << "是素数" << endl;
	else
		cout << "不是素数" << endl;
}

2. 密钥产生

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];
	cout << "大素数 : p = " << p << " q = " << q <<  endl;
 
	n = p * q;
	int On = (p - 1)*(q - 1);
	//用欧几里德扩展算法求e,d
	for (int j = 2; j < On; j += 1331)
	{
		d = ExtendEculid(On, j, 0, 1);
		if (gcd(On,j) == 1 & d>0)
		{
			e = j;
			break;
		}
    }
    cout << "选择e = " << e << " d = " << d << endl;
    cout << "计算d = " << d << endl;
}

3. 广义欧几里得计算乘法逆元

//记gcd(a,b)表示非负整数a,b的最大公因数,那么:gcd(a,b)=gcd(b,a%b)
ll gcd(ll a, ll b)
{
	if (a < b)
	{
		ll temp = b;
		b = a;
		a = temp;
	}
	if (a%b == 0)
		return b;
	else
		return gcd(b, a%b);
}
 
//gcd(n,u)=an+bu;
ll ExtendEculid(ll n1, ll n2, ll b1, ll b2)
{
	ll q, r;
	q = n1 / n2;
	r = n1 - q*n2;
	if (r != 0)
	{
		ll temp = b1 - q*b2;
		ExtendEculid(n2, r, b2, temp);
	}
	if (n2 == 1)
		return b2;
}
 
//调用过程
void Inverse_element()
{
	cout << "u * v == 1(mod n)\n";
	cout << "";
	ll u, n, t;
	cout << "请输入u:";
	cin >> u;
	cout << "请输入n:";
	cin >> n;
	if (gcd(n, u) != 1)
		cout << "两个数不互素,没有乘法逆元!" << endl << endl;
	else
	{
		t = ExtendEculid(n, u, 0, 1);
		if (t < 0)
			t += n;
		cout << u << "mod" << n << "的逆元为" << t << endl;
	}
}

4. 模n的大数幂乘的快速算法

ll Power_mul(ll a,ll b,ll c,ll n)
{
	//初始a=x,b=r,c=1
	while (b != 0)
	{
		while (b % 2 == 0)
		{
			b /= 2;
			a = (a * a) % n;
		}
		b -= 1;
		c = (c * a) % n;
	}
	return	c;
}
 
void PM()
{
	cout << "x^r mod n" << endl;
	ll x, r, n;
	cout << "请输入x:";
	cin >> x;
	cout << "请输入r:";
	cin >> r;
	cout << "请输入n:";
	cin >> n;
	ll out = Power_mul(x, r, 1, n);
	cout << x << "^" << r << " mod " << n << " = " << out << endl;
	
}

5. RSA 加密

void RSA_Encrypt()
{
	int p,q;
	cout << endl;
	cout << "公钥(n, e) : n = " << n << " e = " << e << endl;
	cout << "私钥(d, p, q) : d = " << d << " p = " << p << " q = " << q<< endl;
 
	int i = 0;
	for (i = 0; i < 100; i++)
		Ciphertext[i] = Power_mul(Plaintext[i], e, 1, n);
 
	cout << endl;
	cout << "用公钥(n, e)加密出的密文如下:" ;
	for (i = 0; i < 100; i++)
		cout << Ciphertext[i] << " ";
	cout << endl;
}

6. RSA 解密

void RSA_Decrypt()
{
	int i = 0;
	for (i = 0; i < 100; i++)
		Plaintext_C[i] = Power_mul(Ciphertext[i], d, 1, n);
 
	cout << endl;
	cout << "密文为:" ;
	for (i = 0; i < 100; i++)
		cout << Ciphertext[i] << " ";
	cout << endl;
	cout << endl; 
	cout << "用私钥(n ,e)解密出的明文如下:" ;
	for (i = 0; i < 100; i++)
		printf("%c", Plaintext_C[i]);
	cout << endl;
}

7主函数

int main()
{
	Initialize();
	while (!e)
		RSA_Initialize();
	RSA_Encrypt();
	RSA_Decrypt();
    getchar();
	return 0;
}

实验结果

1.素数生成
在这里插入图片描述

图1 生成的大素数
2.密钥生成
在这里插入图片描述

图2 生成的密钥
3.RSA加密
在这里插入图片描述

图3 RSA加密的明文
在这里插入图片描述

图4 RSA加密的密文
4.RSA解密
在这里插入图片描述

图5 RSA解密的明文和密文
P.S.大素数的生成即首先随机生成一个大奇数并检测它是否为一个素数,迭代直到生成一个符合要求的大素数。大素数的检测使用的是基于大整数运算的Miller-Rabin算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值