实验目的
了解现代密码学的基本原理和数论的基础知识,掌握非对称密码体制的著名代表RSA加密算法的工作原理和流程,并设计实现一个简单的密钥系统。
实验内容
了解加/解密的基本原理和工作过程,用公开密钥对明文进行加密,并用私人密钥对密文进行解密,构造一个简单的 RSA 公开密钥系统。
实验原理
1、RSA算法是由麻省理工学院的 Ron Rivest,Adi Shamir 和Len Adleman 于 1977 年研制并于1978 年首次发表的一种算法,是第一个能同时用于加密和数字签名的算法,且易于理解和操作,因此作为一种通用公开密钥加密方式而受到推崇。RSA是一种分组密码,其中明文和密文都是小于某个 n 的从0 到 n-1 的整数,则分组的
二进制值长度必须小于或等于log2n。若以 M 表示明文分组,而C 表示密文分组,则加密和解密的过程如下:
加密:C=M^e mod n
解密:M’=C^d mod n
发送方和接受方都必须知道n 的值。发送方知道 e 的值,而只有接受方知道d 的值。因此这是一种公开密钥为{e,n},且私有密钥为{d,n}的公开密钥加密算法。此时算法要能够满足公开密钥加密的要求,则必须满足以下条件:
(1) 有可能找到 e、d、n的值,使得对所有 M<n 有
M^(ed) modn = M mod n。
(2)对于所有M<n 的值,要计算 M^e和C^d 相对来说是简单的。
(3)在给定e 和 n 时,判断出d 是不可行的。
2、重点考虑第一个条件:
由 Euler 定理的一个推论:给定两个素数p和 q以及两个整数 n 和m,使得 n=pq 而且0<m<n,并且对于任意整数k,下列关系成立:
m^(kΦ(n)+1)=m
k(p-1)(q-1)+1≡m mod n
其中Φ(n)是欧拉函数,也就是不超过n 且与 n 互素的整数个数。对于素数p 和 q,有Φ(pq)=(p-1)(q-1)。
因此得到需要的关系:ed=kΦ(n)+1,
等价于: ed≡1mod Φ(n) => d≡e-1mod Φ(n)
也就是说:d 和e 是以Φ(n)为模的乘法逆元。
根据模运算规则,它的必要条件是:d、e和Φ(n)是互素的,即gcd(Φ(n),d)=1。3、因此给出RSA 方案:
1. 选择两个大素数p,q(私有,选择)
2. 计算乘积n = p q,得到Φ(n)=(p-1)(q-1)(公开,计算出)
3. 选择随机整数e,其中gcd(Φ(n),e)=1;0<e<Φ(n)(公开,选择)
4. 计算d≡e-1mod Φ(n) (私有,计算出)
5. 私有密钥由{d,n}组成,公开密钥由{e,n}组成。
假设用户 A 公布了它的公开密钥,而用户B 希望向 A 发送一个报文M,那么 B 计算出C=M^e mod n 并传输 C。在收到这个密文时,用户A 通过计算 M’=C^d mod n 进行解密。
3、编程一个简单的RSA 加、解密系统。
(1)假设用户A 选择两个素数 p 和q,计算得到 n=pq 和Φ(n)=(p-1)(q-1)。选择一个加密密钥e,它小于Φ(n)且与Φ(n)互素。计算解密密钥d≡ e-1 mod Φ(n)。则用户A 公布公开密钥{e,n},自己拥有私有密钥{d,n}。
(2)用户B 使用用户 A 的公开密钥e 和 n 对报文M 进行加密,得到 C= M^e mod n,并发送给用户A。
(3)用户A 收到加密的报文后,使用自己的私有密钥 d 和n 对加密报文 C 进行解密,恢复得到明文M=C^d mod n。
实验代码:
#include <iostream> using namespace std; int MOD; int extended_euclid(int a, int b, int &x, int &y) { if(b == 0) { x = 1; y = 0; return a; } int gcd = extended_euclid(b, a % b, x, y); int t = x % MOD; x = y % MOD; y = ((t - a / b * x) % MOD + MOD) % MOD; return gcd; } int main() { int p, q, i, d; cout << "输入一个质数p:"; cin >> p; cout << "输入一个质数q:"; cin >> q; int n = p * q; cout<<"分组加密时,每个分组的大小不能超过p*q="; cout << n << endl; //求得φ(n)=(p-1)*(q-1)的值 MOD = (p - 1) * (q - 1); cout << "模φ(n)=(p-1)*(q-1)="; cout << MOD << endl << endl; //选取与φ(n)互质的公钥e int e; cout << "输入与φ(n)互质的公钥e:"; cin >> e; //由e和φ(n)生成私钥d int x, y; extended_euclid(e, MOD, d, y); while(d < 0) d += MOD; cout << "通过调用扩展欧几里德算法,求得密钥d为:" << d << endl; //利用生成的公钥{e,n}对明文M进行加密 int M, C; cout << "现在公钥{e,n}、私钥{d,n}均已生成完毕。\n\n请输入需要传输的明文内容进行加密(如9726):"; cin >> M; C = 1; for(i = 1; i <= e; i++) C = C * M % n; cout << "明文M=" << M << "经加密后得到密文C=M^e(mod n):" << C << endl; //利用生成的私钥私钥{e,n}对密文C进行解密 M = 1; for(i = 1; i <= d; i++) M = M * C % n; cout << "密文C=" << C << "经解密后得到明文M=C^d(mod n):" << M << endl; return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。