实验环境:Kali虚拟机,OPENSSL库
实验原理:
中国剩余定理
模重复平方运算
RSA算法:
RSA算法给予一个十分简单的数论事实:将两个大素数想成十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密秘钥。RSA算法主要包括:秘钥生成,加密过程和解密过程。
(1)加密过程。在秘钥生成过程中,首先生成两个大的质数(素数)p和q,令n=p*q;m=(p-1)*(q-1),选取较小的数e,使e 和m互质,即e和m的最大公约数为1,然后生成d,使d*emod m=1,最后丢弃P,q,m,则公钥为e,n,私钥为d和n.
(2) 加密过程。将明文x加密成密文y的计算公式为:x=y^d mod n。从公式可见,加密牵涉到明文和公钥。因此,密文即使被截获,也无法被解读。
(3) 解密过程。将密文y解密成明文x的计算公式为:x=y^d mod n。从公式可见,解密至牵涉到私钥和密文。因此,只要保管好私钥,不泄密,就可以放心地把密文和公钥公开。
实验要求:
使用中国剩余定理和模重复平方运算简化RSA的计算量,加速RSA的实现,使用时间戳函数记录两次的运行时间,进行对比分析
明文为 姓名+学号
使用中国剩余定理和模重复平方运算简化RSA的计算量,加快加解密的速度
使用时间戳函数记录两次的运行时间,进行对比
RSA密钥生成算法具体如下:
(1)随机选取两个素数,作为p和q.
(2)计算n=q*p,m=(q-1)*(p-1);
(3)随机选取e,使e 与m互质.
(4)利用扩展欧几里得算法,计算d使d*e mod m=1.
(5)得到公钥(e,n)和私钥(d,n)。
RSA加密算法具体如下:
(1)输入明文x(数字)
(2)利用模运算的性质,计算密文y=x^e mod n。
RSA解密算法具体如下:
(1)输入密文y(数字)。
(2)利用模运算的性质,计算密文x=y^d mod n。
实验思路:
我们已知RSA算法的安全性是基于大整数分解难题的,那么这也会意味着n=p*q的位数会特别长,假设p,q长度都是1024比特,那么n的长度会变成2048比特
那么在进行
C=M^e(mod n) 以及 M=C^d(mod n) 时的计算量会非常大
我们已知中国剩余定理的基本思路如下
接下来我们来进行优化
以解密过程为例
M=C ^d(mod n)
对于n而言,他是一个2048比特的数,使用中国剩余定理,m1=p,m2=q,m=m1*m2
对于d而言,可以把d变成d1( 其中d1=d-k*fai(p) ),因为根据欧拉定理可以推到结论的成立,推理过程如下所示:
对于c而言,可以把c变成c1(其中C1=c mod p),推理过程如下:
观察上式,结合数学中的二项式定理可以发现
除了第一项不含有p之外,其余每一项都含有p
然后根据同余的知识,含有p的每一项mod p之后都会变成0
所以化简步骤正确,上式成立
综上所述
通过对c d n 都进行了化简,RSA的加解密速度将会大大提升
源代码展示:
#include<stdio.h>
#include <string.h>
#include<openssl/bn.h>
#define NBITS 256
void str_2_hex_str(char *dest, char *src)
{
int size = strlen(src);
int i,j;
for (i = 0, j = 0; i < size; i++) {
sprintf(&dest[j], "%02X", src[i]);
j+=2;
}
dest[j] = '\0';
}
void printBN(char *msg,BIGNUM *a)
{
char *number_str=BN_bn2hex(a);
printf("%s %s\n",msg,number_str);
OPENSSL_free(number_str);
}
int main(){
char p1[33]="F7E75FDC469067FFDC4E847C51F452DF";
char res[32];
char data[64];
char p2[33]="F7E75FDC469067FFDC4E847C51F452DE";
char q1[33]="E85CED54AF57E53E092113E62F436F4F";
char q2[33]="E85CED54AF57E53E092113E62F436F4E";
char e1[33]="0D88C3";
char l[33]="00000000000000000000000000000001";
scanf("%s",data);
BN_hex2bn(&l,l);
str_2_hex_str(res,data);
BN_CTX *ctx =BN_CTX_new();
BIGNUM *p=BN_new();
BN_hex2bn(&p,p1);
BIGNUM *q=BN_new();
BN_hex2bn(&q,q1);
//p2=p1-1=fp
//q2=q2-1=fq
BIGNUM *P=BN_new();
BN_hex2bn(&P,p2);
BIGNUM *Q=BN_new();
BN_hex2bn(&Q,q2);
//mulity n =p*q
BIGNUM *n=BN_new();
BN_mul(n,p,q,ctx);
//mulity fn=(p-1)*(q-1)
BIGNUM *fn=BN_new();
BN_mul(fn,P,Q,ctx);
BIGNUM *e=BN_new();
BN_hex2bn(&e,e1);
BIGNUM *d=BN_new();
//figure d which meet e*d=1 mod(fn)
BN_mod_inverse(d,e,fn,ctx);
//
BIGNUM *M=BN_new();
BN_hex2bn(&M,res);
BIGNUM *c=BN_new();
//figure c which meet c=M^e mod n
//BN_mod_exp(c,M,e,n,ctx);
BIGNUM *m=BN_new();
//figure m which meet M=c^d mod n
//BN_mod_exp(m,c,d,n,ctx);
//定义可能用到的所有变量
BIGNUM *d1=BN_new();
BIGNUM *d2=BN_new();
BIGNUM *c1=BN_new();
BIGNUM *c2=BN_new();
BIGNUM *e11=BN_new();
BIGNUM *e12=BN_new();
BIGNUM *M1=BN_new();
BIGNUM *M2=BN_new();
BIGNUM *a1=BN_new();
BIGNUM *a2=BN_new();
BIGNUM *y1=BN_new();
BIGNUM *y2=BN_new();
//求出中国剩余定理所需要的所有变量
BN_mod_mul(d1,d,l,p,ctx);
BN_mod_mul(d2,d,l,q,ctx);
BN_mod_mul(c1,c,l,p,ctx);
BN_mod_mul(c2,c,l,q,ctx);
BN_mod_mul(e11,e,l,p,ctx);
BN_mod_mul(e12,e,l,q,ctx);
//this m means mingwen1
BN_mod_mul(M1,M,l,p,ctx);
BN_mod_mul(M2,M,l,q,ctx);
BN_mod_exp(a1,M1,e11,p,ctx);
BN_mod_exp(a2,M2,e12,q,ctx);
//figure out modular inverse
//this process is about jiemi
BN_mod_inverse(y1,q,p,ctx);
BN_mod_inverse(y2,p,q,ctx);
BIGNUM *result=BN_new();
//result= a1*y1*q+a2*y2+p mod n根据中国剩余定理得出结果,并将结果存到result中
BIGNUM *result1=BN_new();
BIGNUM *result2=BN_new();
//result1=a1*y1*q;
//result2=a2*y2*p;
BIGNUM *result11=BN_new();
BIGNUM *result12=BN_new();
BN_mul(result11,a1,y1,ctx);
BN_mul(result12,a2,y2,ctx);
BN_mul(result1,result11,q,ctx);
BN_mul(result2,result12,p,ctx);
BN_add(result,result1,result2);
printBN("p:",p);
printBN("q:",q);
printBN("N:",n);
printBN("fai(n):",fn);
printBN("e:",e);
printBN("d:",d);
printBN("M:",M);
printBN("m^e mod n = \n",c);
printBN("c^d mod n = \n",m);
printf("result=",result);
}
运行结果:
运行结果和我那篇没有优化过的博客一样,这里因为隐私原因没有展示,那篇博客也没有展示最终的结果,大家自行运行就行了
中国剩余定理(CRT)在RSA中的应用:
快速乘法运算:在RSA算法中,明文和密文都是以大整数的形式存在。中国剩余定理允许我们把一个大整数分解成几个较小整数的乘积,然后分别对这些较小的数进行乘法运算,最后再将结果合并起来。这种方法可以显著提高乘法运算的速度。
模数分解:在RSA解密过程中,可以使用CRT将大模数n=p×q分解为两个较小的模数。这样,我们可以分别对其进行幂模运算,然后再利用CRT将结果合并回原始模数
减少计算量:由于分解之后的数通常比n小得多,使用CRT可以减少幂模运算的计算量,从而加快解密过程。
模重复平方运算(Modular Exponentiation)在RSA中的应用:
提高效率:模重复平方是一种高效的幂运算方法,特别是在模数很大的情况下。它通过将指数分解成二进制形式,并利用平方和减半的方式来减少必要的乘法次数。
简化实现:模重复平方提供了一种简单且高效的方式来实现幂模运算,这是RSA加密和解密过程中的核心步骤。
减少存储需求:由于模重复平方可以在每一步中只保存中间结果,它减少了在计算过程中对存储的需求。
防止溢出:在处理非常大的数时,模重复平方可以防止整数溢出的问题,因为每一步的计算都保持在模数的范围内。
优化作用:
加速运算:通过使用CRT和模重复平方,RSA算法的运算速度得到了显著提升,尤其是在解密过程中。
减少资源消耗:这两种方法减少了计算过程中所需的计算资源和存储资源。
提高安全性:优化算法的执行速度和效率,可以减少在实际应用中因性能问题而引入的潜在安全风险。
适应现代需求:随着数据量的增加和对加密速度要求的提高,这些优化方法使得RSA算法能够更好地适应现代加密需求。
实验中遇到的问题:
OPENSSL在编写程序时
1不允许一个大数和int类型的数做运算,就算不定义类型,比如直接拿大数减去一个数字,这个数字也会被系统默认为int类型,虽然在程序语法上可以通过,但是结果不对,会有语义错误
2不允许嵌套函数的出现,在编写程序时,为了减少变量的定义,我使用了嵌套函数,但是程序会报错,OPENSSL中不允许使用嵌套函数
实验感悟:
OPENSSL是一个功能很强大的库,但是在使用时会有点略显得不太容易上手
中国剩余定理和模重复平方运算对于RSA的加速作用很明显,尤其是当数据特别大的时候,计算量会大大的简化,比如中国剩余定理可以让1024bit的数变成512bit的数。
使用这两个定理可以实现对c d m e的优化,即最后的加解密过程都可以被优化。