RSA加密支持中文和文件加密,效率已优化【中文变量版】
本帖最后由 xuson 于 2023-4-13 14:50 编辑由于使用了24bit(0xFFFFFF)来换算,导致加密解密的时候比较耗时(加密700多字节大概在48秒,待优化)。
加密的内容会双字节合并,代码里边也注释了3字节合并的有能力的可以尝试使用。
由于使用的素数比较小,比较容易被破解。
#ifndef xRSA_H
#define xRSA_H
#include <string>
#include <iostream>
#include <ctime>
#include <sys/timeb.h>
using std::cout;
using std::endl;
int 素数 = {
1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,
1151,1153,1163,1171,1181,1187,1193,1217,1223,1237,
1217,1223,1231,1237,1259,1277,1283,1367,1381,1399,
1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,
1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,
1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,
2521,2531,2539,2543,2549,2551,2557,2579,2591,2593,
2803,2819,2833,2837,2843,2851,2857,2861,2879,2887,
2897,2903,2909,2917,2927,2939,2953,2957,2963,2969,
3067,3079,3083,3089,3109,3119,3121,3137,3163,3167,
3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,
3559,3571,3581,3583,3593,3607,3613,3617,3623,3631, //120
65537,65551,65579,65599,65809,65831,65851,65867,65899,66137,
66161,66179,66191,66221,66293,66529,66553,66571,66593,66617,
70249,70289,70309,70313,70583,70619,70639,70667,70921,70957,
75937,75983,75989,76003,76081,76123,76159,76231,76259,76303,
76369,76421,76471,76507,76541,76597,76649,76679,78989,79063};
class x加密类
{
public:
x加密类() {
this->_乘积 = this->_私钥 = this->_公钥 = 1;
}
~x加密类() {
}
unsigned long 加密(const char *明文, unsigned long 明文长度, char *密文) {
if (this->_公钥==0) return 0;
if (密文==0) {
密文 = (char*)malloc(sizeof(char)*明文长度 * 3 + 1);
memset(&密文, 0, 明文长度 * 3 + 1);
}
unsigned long id = 0;
for (int i = 0; i < 明文长度; i+=2)
{
this->_Num = (unsigned char)明文;
this->_Num+= (unsigned char)明文 * 0x100;
//this->_Num+= (unsigned char)明文 * 0x10000;
this->_N = PowMod(this->_Num, this->_私钥, this->_乘积);
密文 = (unsigned char)( this->_N & 0xFF );
密文 = (unsigned char)((this->_N & 0xFF0000) / 0x10000);
密文 = (unsigned char)((this->_N & 0xFF00) / 0x100);
//cout << std::hex << (int)this->_N << endl;
//cout << std::hex << (int)密文 << endl;
//cout << std::hex << (int)密文 << endl;
//cout << std::hex << (int)密文 << endl;
}
return id;
}
unsigned long 解密(const char *密文, unsigned long 密文长度, char *明文) {
if (this->_私钥==0) return 0;
if (明文==0) {
明文 = (char*)malloc(sizeof(char)*密文长度 + 1);
memset(&明文, 0, 密文长度 + 1);
}
unsigned long id = 0;
for (int i = 0; i < 密文长度; i += 3)
{
this->_N = (unsigned char)密文;
this->_N+= (unsigned char)密文 * 0x10000;
this->_N+= (unsigned char)密文 * 0x100;
this->_Num = PowMod(this->_N, this->_公钥, this->_乘积);
明文 = (unsigned char)((this->_Num & 0xFF00)/ 0x100);
明文 = (unsigned char)(this->_Num & 0xFF);
//明文 = (unsigned char)((this->_Num & 0xFF0000)/ 0x10000);
}
return id;
}
//产生私钥和公钥
void 生成密钥(unsigned __int64 公钥=0, unsigned __int64 私钥=0, unsigned __int64 乘积=0)
{
if ((公钥!=0 || 私钥!=0) && 乘积!=0) {
this->_乘积 = 乘积;
this->_公钥 = 公钥;
this->_私钥 = 私钥;
} else {
this->_公钥 = 素数; // 0x010001;
unsigned __int64 p = 素数;
unsigned __int64 q = 素数;
while(p==q) { q = 素数; }
this->_乘积 = p * q;
this->_私钥 = reverseMod(this->_公钥, (p - 1)*(q - 1));
cout << "p:" << p << ", q:" << q << endl;
}
char cN, cA, cB;
sprintf(cN, "0x%06X", this->_乘积);
sprintf(cA, "0x%06X", this->_公钥);
sprintf(cB, "0x%06X", this->_私钥);
cout << "公钥:" << "(" << cN << "," << cA << ")" << endl;
cout << "私钥:" << "(" << cN << "," << cB << ")" << endl;
}
private:
unsigned __int64 _Num, _N;
unsigned __int64 _乘积; //n=p*q
unsigned __int64 _私钥; //a对于φ(n)的模反元素
unsigned __int64 _公钥;
//模乘运算,返回值 x=a*b mod n
//模幂运算,返回值 x=base^pow mod n
unsigned __int64 PowMod(unsigned __int64 值, unsigned __int64 密钥, unsigned __int64 乘积)
{
if (密钥 == 1)
return 值 % 乘积;
else
return (PowMod(值, 密钥 / 2, 乘积)*PowMod(值, 密钥 - 密钥 / 2, 乘积)) % 乘积;
}
//返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
__int64 extend_gcd(__int64 one, __int64 two, __int64 &x, __int64 &y) {
if (one == 0 && two == 0) return -1;//无最大公约数
if (two == 0) {
x = 1; y = 0; return one;
}
__int64 d = extend_gcd(two, one%two, y, x);
y -= one / two * x;
return d;
}
//ax = 1(mod n) 求X
__int64 reverseMod(__int64 one, __int64 two) {
__int64 x, y;
__int64 d = extend_gcd(one, two, x, y);
if (d == 1)
return (x%two + two) % two;
else return -1;
}
unsigned long time_stamp;
/* ================================
函数: Rand
参数: seeds=种子数,最大值
描述: 随机产生整型数字
================================ */
unsigned int Rand(const int seeds)
{
if (seeds == 0) return seeds;
struct timeb timeSeed;
ftime(&timeSeed);
unsigned long _timestamp = ((timeSeed.time & 0xFFFFFFFFUL) * 0x10000UL + timeSeed.millitm) & 0xFFFFFFFFUL;
if (_timestamp - time_stamp > 100) {
time_stamp = _timestamp;
srand(time_stamp); // milli time
}
return rand() % seeds;
}
};
#endif
学习了·· 说明一下:
1、现在这个思路是按网络上解释的RSA加密解密去实现,加上自己的了解处理了中文的加密解密。但是效果不好。
2、后续在此基础上增加变种处理,使用16bit的素数(short类型)会提高更快的加密解密速度。
现在主要是卡在中文字符如果拆分组合才能更好的加密解密。 感谢分享 本帖最后由 xuson 于 2023-4-20 15:24 编辑
最新代码使用Short类型作为密钥(16bit)数值,速度效果提升几十倍。
github源码库: https://github.com/CSXing/RSA-Encryption-and-decryption
页:
[1]