rsa 长密钥实现及测试

1. 今天看了一下RSA非对称的c++实现。

网上有简单的实现,但是生成的密钥太短,并且运行效率很差。

2. 用boost实现的版本。可以运行在vs2010 及以上的版本。

void testbigRSA()
{
	using namespace MYRSA;

	RSA_bigPrime bsa_bigPrime;
	Key2 key = bsa_bigPrime.getKey();

	cout << "钥匙如下:"<< endl;
	cout << "公钥:" << key.pkey << endl;
	cout << "加密密钥:" << key.ekey << endl;
	cout << "解密密钥:" << key.dkey << endl;

	std::string str = "abcdefghijklmnopqrstuvwxyz1234567890";

	std::cout << "加密的串:" << str << std::endl;

	//std::cout << "请输入字符串:" << std::endl;
	//std::getline(std::cin, str);

	//加密后的
	std::vector<bm::int1024_t> str_ec = bsa_bigPrime.Ecrept(str, key.ekey, key.pkey);

	// 网络传的串
	std::string strOut;
	bsa_bigPrime.getVecString(str_ec, strOut);
	size_t nlen = strOut.length();

	// 本地收到解码
	std::string str_dec;
	vector<bm::int1024_t> vecSource;
	{
		bsa_bigPrime.getDecodeVec(vecSource, strOut);

		str_dec = bsa_bigPrime.Decrept(vecSource, key.dkey, key.pkey);
		std::cout << "密文:" << std::endl;
	}

	bsa_bigPrime.printInfo(vecSource);
	
	//解密后的输出
	std::cout << "解密后的字符串" << std::endl;
	std::cout << str_dec << std::endl;

	return;
}

rsa.h

#pragma once
#include <string>
#include <vector>
#include <time.h>
#include <fstream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/random.hpp>
#include <boost/multiprecision/miller_rabin.hpp>

namespace bm = boost::multiprecision;
namespace rm = boost::random;
namespace MYRSA {
	struct Key2
	{
		//公钥(ekey, pkey): (e,n)
		bm::int1024_t pkey;		//n
		bm::int1024_t ekey;		//e
		//私钥(dkey, pkey): (d, n)
		bm::int1024_t dkey;		//d
	};

	class RSA_bigPrime
	{
	public:
		RSA_bigPrime();
		Key2 getKey();
		void ecrept(const char* plain_file_in, const char* ecrept_file_out,
			bm::int1024_t ekey, bm::int1024_t pkey);
		void decrept(const char* ecrept_file_in, const char* plain_file_out,
			bm::int1024_t dkey, bm::int1024_t pkey);

		std::vector<bm::int1024_t> Ecrept(std::string& str_in, bm::int1024_t ekey, bm::int1024_t pkey);
		std::string Decrept(std::vector<bm::int1024_t>& ecrept_str, bm::int1024_t dkey, bm::int1024_t pkey);

		void printInfo(std::vector<bm::int1024_t>& ecrept_str);

		bool getDecodeVec(std::vector<bm::int1024_t>&vecOut_, std::string& in_);
		bool getVecString(std::vector<bm::int1024_t>&vec_, std::string& out_);

	private:
		//加密解密单个信息,加密时key传e,pkey传n;解密时key传d,pkey传n
		bm::int1024_t ecrept(bm::int1024_t msg, bm::int1024_t key, bm::int1024_t pkey);
		bm::int1024_t produce_prime();
		bool is_bigPrime(bm::int1024_t prime);
		void produce_keys();
		bm::int1024_t produce_pkey(bm::int1024_t prime1, bm::int1024_t prime2);
		bm::int1024_t produce_orla(bm::int1024_t prime1, bm::int1024_t prime2);
		bm::int1024_t produce_ekey(bm::int1024_t orla);
		bm::int1024_t exgcd(bm::int1024_t ekey, bm::int1024_t orla, bm::int1024_t& x, bm::int1024_t& y);

		bm::int1024_t produce_dkey(bm::int1024_t ekey, bm::int1024_t orla);
		bm::int1024_t produce_gcd(bm::int1024_t ekey, bm::int1024_t orla);

		std::vector<bm::int1024_t> splitString(const std::string & s, char delimiter);
	private:
		Key2 _key;
	};
}

rsa.cpp

#include "RSA_bigPrime.h"
#include <iostream>

namespace MYRSA {
	RSA_bigPrime::RSA_bigPrime()
	{
		produce_keys();
	}

	Key2 RSA_bigPrime::getKey()
	{
		return _key;
	}

	void RSA_bigPrime::ecrept(const char* plain_file_in, const char* ecrept_file_out, bm::int1024_t ekey, bm::int1024_t pkey)
	{
		// 	std::ifstream fin(plain_file_in, std::ifstream::binary);
		// 	std::ofstream fout(ecrept_file_out, std::ofstream::binary);
		// 	if (!fin.is_open()){
		// 		std::cout << "file open filed" << std::endl;
		// 		return;
		// 	}
		// 	const int NUM = 256;
		// 	char buf[NUM];
		// 	bm::int1024_t buf_out[NUM];
		// 	std::streamsize curNum;
		// 	while (!fin.eof())
		// 	{
		// 		fin.read(buf, NUM);
		// 		curNum = fin.gcount();	//当前读取的字节数
		// 		for (int i = 0; i < curNum; i++){
		// 			buf_out[i] = ecrept((bm::int1024_t)buf[i], ekey, pkey);
		// 		}
		// 		fout.write((char*)buf_out, curNum * sizeof(bm::int1024_t));
		// 	}
		// 
		// 	fin.close();
		// 	fout.close();
	}

	void RSA_bigPrime::decrept(const char* ecrept_file_in, const char* plain_file_out, bm::int1024_t dkey, bm::int1024_t pkey)
	{
		// 	std::ifstream fin(ecrept_file_in, std::ifstream::binary);
		// 	std::ofstream fout(plain_file_out, std::ofstream::binary);
		// 	if (!fin.is_open()){
		// 		std::cout << "file open filed" << std::endl;
		// 		return;
		// 	}
		// 	const int NUM = 256;
		// 	bm::int1024_t buf[NUM];		//要解密的
		// 	char buf_out[NUM];	//输出
		// 	std::streamsize curNum;
		// 	while (!fin.eof())
		// 	{
		// 		fin.read((char*)buf, NUM * sizeof(bm::int1024_t));
		// 		curNum = fin.gcount();	//当前读取的字节数
		// 		curNum /= sizeof(bm::int1024_t);
		// 		for (int i = 0; i < curNum; i++){
		// 			buf_out[i] = ecrept(buf[i], dkey, pkey);
		// 		}
		// 		fout.write(buf_out, curNum);
		// 	}
		// 
		// 	fin.close();
		// 	fout.close();
	}

	std::vector<bm::int1024_t> RSA_bigPrime::Ecrept(std::string& str_in, bm::int1024_t ekey, bm::int1024_t pkey)
	{
		std::vector<bm::int1024_t> msg_des;
		for (int i = 0; i < str_in.size(); i++) {
			char msg = str_in.at(i);
			msg_des.push_back(ecrept(msg, ekey, pkey));
		}

		return msg_des;
	}

	std::string RSA_bigPrime::Decrept(std::vector<bm::int1024_t>& ecrept_str, bm::int1024_t dkey, bm::int1024_t pkey)
	{
		std::string msg_out;
		for (int i = 0; i < ecrept_str.size(); i++) {
			bm::int1024_t msg = ecrept_str.at(i);
			bm::int1024_t out = ecrept(msg, dkey, pkey);

			msg_out.push_back((char)boost::lexical_cast<int>(out));
		}
		return msg_out;
	}

	void RSA_bigPrime::printInfo(std::vector<bm::int1024_t>& ecrept_str)
	{
		for (int i = 0; i < ecrept_str.size(); i++)
		{
			std::cout << ecrept_str[i] << " ";
		}

		std::cout << std::endl;
	}

	bm::int1024_t RSA_bigPrime::produce_prime()
	{
		//mt19937: 一种随机数产生器
		rm::mt19937 gen((unsigned int)time(nullptr));
		//指定随机数的范围:2 ~ (1 << 768)
		rm::uniform_int_distribution<bm::int1024_t> dist(2, bm::int1024_t(1) << 28);
		bm::int1024_t prime = 0;
		while (1) {
			prime = dist(gen);
			if (is_bigPrime(prime)) {
				break;
			}
		}
		return prime;
	}

	bool RSA_bigPrime::is_bigPrime(bm::int1024_t digit)
	{
		rm::mt11213b gen((unsigned int)time(nullptr));
		if (miller_rabin_test(digit, 25, gen))
		{
			if (miller_rabin_test((digit - 1) / 2, 25, gen))
			{
				return true;
			}
		}
		return false;
	}

	//模幂运算
	bm::int1024_t RSA_bigPrime::ecrept(bm::int1024_t msg, bm::int1024_t key, bm::int1024_t pkey)
	{
		bm::int1024_t msg_out = 1;
		bm::int1024_t a = msg;	// a:需要加密的信息  key: b  pkey: c
		bm::int1024_t b = key;
		bm::int1024_t c = pkey;
		while (b) {
			if (b & 1) {
				msg_out = (msg_out * a) % c;
			}
			b >>= 1;
			a = (a * a) % c;
		}
		return msg_out;
	}

	//产生成员变量公钥和私钥
	void RSA_bigPrime::produce_keys()
	{
		bm::int1024_t prime1 = produce_prime();
		bm::int1024_t prime2 = produce_prime();
		while (prime1 == prime2) {
			prime2 = produce_prime();
		}
		std::cout << "素数产生成功" << std::endl;
		//公钥(e, n) 私钥(d, n)
		_key.pkey = produce_pkey(prime1, prime2);	//n
		std::cout << "n 产生成功" << std::endl;
		bm::int1024_t orla = produce_orla(prime1, prime2);	//f(n)
		std::cout << "orla 产生成功" << std::endl;
		_key.ekey = produce_ekey(orla);			//e
		std::cout << "e 产生成功" << std::endl;
		_key.dkey = produce_dkey(_key.ekey, orla);	//d
		std::cout << "d 产生成功" << std::endl;
	}

	//求n
	bm::int1024_t RSA_bigPrime::produce_pkey(bm::int1024_t prime1, bm::int1024_t prime2)
	{
		return prime1 * prime2;
	}

	//求f(n)
	bm::int1024_t RSA_bigPrime::produce_orla(bm::int1024_t prime1, bm::int1024_t prime2)
	{
		return (prime1 - 1) * (prime2 - 1);
	}

	//求e
	bm::int1024_t RSA_bigPrime::produce_ekey(bm::int1024_t orla)
	{
		srand((unsigned int)time(nullptr));
		bm::int1024_t e;
		//选取e,在(1, f(n))--->[2, f(n)-1]中间选一个和f(n)互质的数,即找一个素数
		while (1) {
			e = rand() % orla;
			if (e > 1 && produce_gcd(e, orla) == 1) {
				break;
			}
		}
		return e;
	}

	//求d
	bm::int1024_t RSA_bigPrime::produce_dkey(bm::int1024_t ekey, bm::int1024_t orla)
	{
		bm::int1024_t d, y;
		exgcd(ekey, orla, d, y);
		return (d % orla + orla) % orla;
	}

	bm::int1024_t RSA_bigPrime::produce_gcd(bm::int1024_t ekey, bm::int1024_t orla)
	{
		bm::int1024_t a = ekey;
		bm::int1024_t b = orla;
		bm::int1024_t tmp;
		while (tmp = a % b) {
			a = b;
			b = tmp;
		}
		return b;
	}

	bm::int1024_t RSA_bigPrime::exgcd(bm::int1024_t ekey, bm::int1024_t orla
		, bm::int1024_t& x, bm::int1024_t& y)
	{
		if (orla == 0) {
			x = 1;
			y = 0;
			return ekey;
		}
		bm::int1024_t gcd = exgcd(orla, ekey % orla, x, y);
		bm::int1024_t x1 = x, y1 = y;
		x = y1;
		y = x1 - (ekey / orla) * y1;
		return gcd;
	}

	std::vector<bm::int1024_t> RSA_bigPrime::splitString(const std::string& s, char delimiter)
	{
		std::vector<bm::int1024_t> tokens;
		std::string token;
		std::istringstream tokenStream(s);
		while (std::getline(tokenStream, token, delimiter))
		{
			tokens.push_back(boost::lexical_cast<bm::int1024_t>(token));
		}
		return tokens;
	}

	bool RSA_bigPrime::getDecodeVec(std::vector<bm::int1024_t>&vecOut_, std::string& in_)
	{
		vecOut_ = splitString(in_, ',');
		return false;
	}

	bool RSA_bigPrime::getVecString(std::vector<bm::int1024_t>&vec_, std::string& out_)
	{
		for (int i = 0; i < vec_.size(); i++)
		{
			std::string str = boost::lexical_cast<std::string>(vec_[i]);
			if (str.length() > 0)
				out_ += str + ",";
		}

		if (!out_.empty())
			return true;

		return false;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值