实验四:RSA公钥加密算法
一、实验目的
理解、掌握RAS公钥加密算法的基本过程。
二、实验内容
- 熟悉MPIR大整数运算库函数的调用。
- 利用MPIR大整数运算库函数,实现RSA公钥加密算法。要求:1)RSA模数为2048bit;2)能对一个数据(例如,16进制数“1234567890ABCDEF”)进行加密、解密。
三、RSA公钥加密算法基本原理
RSA具体实现步骤
第一步,随机选择两个不相等的质数p和q。
第二步,计算p和q的乘积n。
第三步,计算n的欧拉函数φ(n)。
第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。
第五步,计算e对于φ(n)的模反元素d。
第六步,将n和e封装成公钥,n和d封装成私钥。
*现实中为了计算快捷,e一般取65537,
加密
me ≡ c (mod n) 信息m加密成C
解密
cd ≡ m (mod n)
四、实验过程
关键代码:
//随机生成一个素数
void gen_prime(mpz_t prime)
{
gmp_randstate_t grt;
gmp_randinit_default(grt);
gmp_randseed_ui(grt, time(NULL));
mpz_t p;
mpz_init(p);
mpz_urandomb(p, grt, 1024); //随机生成1024位的大整数
mpz_nextprime(prime, p); //使用GMP自带的素数生成函数
mpz_clear(p);
}
int _tmain(int argc, _TCHAR* argv[])
{
//公钥私钥中用到的两个大质数p,q,都是1024位
mpz_t p,q; mpz_init(p); mpz_init(q);
gen_prime(p);
gmp_printf ("质数p:%Zd\n", p);
Sleep(1000);//因为根据时间生成,p、q可能会相等,所以等待1s。
gen_prime(q);
gmp_printf ("质数q:%Zd\n", q);
//生成公钥私钥
mpz_t n,e,d; mpz_init(e); mpz_init(n);mpz_init(d);
mpz_mul(n,p,q); //n = p * q
mpz_t fy; mpz_init(fy);
mpz_t pp; mpz_init(pp); mpz_sub_ui(pp,p,1);//pp=p-1
mpz_t qq; mpz_init(qq); mpz_sub_ui(qq,q,1);//qq=q-1
mpz_mul(fy,pp,qq);//fy=(p-1)*(q-1)
mpz_set_ui(e,65537); //e=65537;
mpz_t one; mpz_init(one); mpz_set_ui(one,1);
mpz_t s,t; mpz_init(s); mpz_init(t);
mpz_gcdext(one, s, t, e, fy);//e * s + fy * t = one
mpz_set(d,s);
//pubkey(n,e) selfkey(n,d)
gmp_printf ("pubkey(n,e):(%Zd,%Zd)\n", n,e);
gmp_printf ("selfkey(n,d):(%Zd,%Zd)\n", n,d);
//需要被加密的信息转化成数字,长度小于秘钥n的长度,如果信息长度大于n的长度,那么分段进行加密,分段解密即可。
char *str="1234567890ABCDEF";
mpz_t m; mpz_init(m); mpz_set_str(m,str,16);
gmp_printf ("原消息:%Zd\n", m);
//信息加密,m被加密的信息,c是加密后的信息
mpz_t c; mpz_init(c);
mpz_powm(c,m,e,n);//c=m^e(mod n)
gmp_printf ("加密后的信息:%Zd\n", c);
//信息解密
mpz_t decrypted; mpz_init(decrypted);
mpz_powm(decrypted,c,d,n);
gmp_printf ("解密后的消息:%Zd\n", decrypted);
getchar();
return 0;
}
五、实验结果
可以看到解密后的消息等于原消息