第二周作业--RSA加/解密算法

2. 程序编写。 (30分钟-3小时)
    实现RSA算法 (书籍P40) 。同学们至少实现2.1 与 2.2;实现RSA完整算法的同学,总成绩的基础上加10分。请大家把编程思想与程序实现(源码),发表在CSDN博文上。
2.1: 判断一个正整数是否为质数的算法。函数签名如下
     int isPrime(long a)
    输入:一个长整数a
    输出:返回1(为质数),返回0(非质数)
2.2: 随机生成一个n bit位的长整数。函数签名如下
    long createRndInteger(int n)
    输入:随机数bit位的长度为n(解释:3bit位,则最大为111,最小为100;n bit位,则该数字二进制长度为n)
    输出:返回该随机数
2.3:随机生成一个n bit位的长质数。函数前面如下
    long createRndPrime(int n)
    输入:随机质数的bit位长度为n
    输出:nbit位长度的质数
    关键为使用随机化算法判断一个长整数是否为素数(P33)。
2.4:公开密钥(N,e)的生成算法。 关键为怎样选择一个与(p-1)(q-1)互质的数e。
2.5:保密密钥(N,d)的生成算法。关键是运用扩展Euclid算法,生成e模 (p-1)(q-1)的逆元,见书籍25页。
2.6:RSA加密算法。对消息m=25进行加密,生成密文c。
2.7:RSA解密算法。对密文c进行解密。
算法的C++实现如下:

RSA.H:
#ifndef RSA_H
#define RSA_H

class RSA
{
private:	
	long p;
	long q;
	long N;
	long N2;

	double encrypted;

	int e;
	int d;

public:
	RSA();

	//求两个数的最大公因数
	long GCD(long a, long b);

	//求一个数是否为质数,true:是, false:其它
	bool IsPrime(long num);

	//随机生成一个n bit位长度整数,long为32位,所以bit限制在32位内
	long CreateRandInteger(int n);

	//随机生成一个n bit位长度的质数
	long CreateRandPrime(int n);

	//计算public and private keys
	void CalKeys(int n);

	void RSAEncrypt(int message);

	void RSADecrypt();
};







#endif

RSA.CPP
#include "RSA.h"
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
using namespace std;

RSA::RSA()
{
	p = 0;
	q = 0;
	N = 0;
	N2 = 0;

	encrypted = 0;

	e = 0;
	d = 0;
}

//求两个数的最大公因数
long RSA::GCD(long a, long b)
{
	long temp;

	if (!(a > 0 && b > 0))
	{
		cout << "Invalid a or b!" << endl;

		exit(0);
	}

	if (b > a)
	{
		temp = b;
		b = a;
		a = temp;
	}

	while ((temp = a % b) != 0)
	{
		a = b;
		b = temp;
	}

	return b;
}


//求一个数是否为质数,true:是, false:其它
bool RSA::IsPrime(long num)
{
	if (num < 1)
	{
		cout << "Invalid input number:not positive number" << endl;

		exit(0);
	}
	else if (1 == num)
	{
		cout << "1 is either a prime or a composite number!" << endl;

		exit(0);
	}

	for (int i = 2; i <= sqrt(num); i++)
	{
		if (0 == num % i)
		{
			return false;
		}
	}

	return true;
}


//随机生成一个n bit位长度整数,long为32位,所以bit限制在32位内
long RSA::CreateRandInteger(int n)
{
	if (n < 1 || n > 32)
	{
		cout << "Invalid bits!" << endl;

		exit(0);
	}

	int* temp = new int[n];
	temp[0] = 1;

	//逐位生成整数的各位,数组下标[0--n-1]表示生成的数的最高位到最低位
	for (int i = 1; i < n; i++)
	{
		//因为随机数的产生依赖于系统时间,为了防止在时间单位内CPU做大量的无用重复计算,所以休眠25ms
		Sleep(25);                                 

		srand(i * (unsigned int)time(NULL));
		temp[i] = rand() % 2;
	}

	//将生成的数以十进制显示
	unsigned long bigInt = 0;
	for (int j = 0; j < n; j++)
	{
		if (1 == temp[j])
		{
			bigInt += temp[j] << (n-j-1);
		}		
	}

	delete[] temp;

	return bigInt;
}

//随机生成一个n bit位长度的质数
long RSA::CreateRandPrime(int n)
{
	unsigned long temp = CreateRandInteger(n);

	while (!IsPrime(temp))
	{  
		temp = CreateRandInteger(n);
	}

	return temp;
}

void RSA::CalKeys(int n)
{
	//unsigned long p = 0;
	//unsigned long q = 0;


	//计算p、q的值
	p = CreateRandPrime(n);
	q = CreateRandPrime(n);

	while (p == q)
	{
		q = CreateRandPrime(n);
	}

	N = p * q;
	N2 = (p-1) * (q-1);
	//unsigned long N = p * q;
	//unsigned long N2 = (p-1) * (q-1);

	//计算加密指数e
	//int e;
	for (e = 2; ; e++)
	{
		if (1 == GCD(e, N2))
		{
			break;
		}
	}

	//计算解密指数d
	//int d;
	for (int i = 1; ; i++)
	{

		if (0 == (N2 * i + 1) % e)
		{
			d = (N2 * i + 1) / e;

			break;
		}
	}

	cout << n << " bits integer number's RSA public and private keys: " << endl;
	cout << "PublicKey(" << N << ", " << e << ")" << endl;
	cout << "PrivateKey(" << N << ", " << d << ")" << endl;
}

void RSA::RSAEncrypt(int message)
{
	encrypted = fmod(pow(message, e), N);

	cout << "The original message: " << message << endl;
	cout << "After encryption: " << endl;
	cout << "The encrypted message: " << encrypted << endl;
}

void RSA::RSADecrypt()
{
	encrypted = fmod(pow(encrypted, d), N);

	cout << "After decryption: " << endl;
	cout << "The original message: " << encrypted << endl;
}

main.cpp:
#include "RSA.h"


void main()
{
	//cout << GCD(1035, 759) << endl;
	//cout << IsPrime(12) << endl;
	
	//CreateRandInteger(32);
	//cout << CreateRandPrime(32) << endl;
	RSA rsa;

	rsa.CalKeys(4);
	rsa.RSAEncrypt(25);
	rsa.RSADecrypt();
}

该算法已经能够成功的求出RSA的公钥和私钥,用系统自带的计算器也已经验证成功了,但程序的RSAEncrypt()和RSADecrypt()仍然有一点小问题,不能正常输出加/解密后的结果,这个问题还在解决中。还有,程序要运行比较长的时间才能求出 公钥和私钥,这一点还需要改进。
经过测试发现,当生成的数的位数超过4bit之后,输出结果就显示不正常,调试后发现,是在进行RSA加/解密运算时要执行高次幂运算,产生的运算结果超过64位,导致溢出,所以显示结果不正常,解决方案还在探索中...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值