RSA加密算法(公钥+私钥加密)

公开密钥加密

公开密钥加密(public-key cryptography),也成为非对称加密,是密码学的一种算法,他需要两个密钥,一个是公开密钥,另一个是私有密钥,一个用作加密的时候,另一个则用作解密。

  • 明文:需要加密的内容,成为明文。
  • 密文:使用密钥把明文加密后的内容。只能用相应的另一个密钥才能解密得到原来的明文。甚至连最初用来加密的密钥也不能用作解密。

对称加密&&非对称加密

  • 对称加密:加密和解密都是用同一个密钥的算法,称作对称加密。
  • 非对称加密:加密和解密需要不同的密钥。

因为公钥加密的信息只用私钥才能解的开,所以只要私钥不泄露,通信就是安全的。

今天这里只介绍RSA非对称加密。

加密过程

在数学上d(c(x))=x,来表示加密解密过程。

这里我们使用典型的爱丽丝与鲍勃假设来解释(来自维基)。

  • 1.爱丽丝与鲍勃事先互不认识,也没有可靠安全的沟通渠道,但爱丽丝现在却要通过不安全的互联网向鲍勃发送消息。
  • 2.爱丽丝撰写好原文,原文在未加密的状态下称之为明文x。
  • 3.鲍勃使用密码学安全伪随机数生成器产生一对密钥,其中一个作为公钥c,另一个作为私钥d.
  • 4.鲍勃可以用任何方法发送公钥c给爱丽丝,即使伊夫在中间窃听到c也没关系。
  • 5.爱丽丝用公钥c把明文x进行加密,得到密文c(x).
  • 6.爱丽丝可以用任何方法传输密文c(x)给鲍勃,即使伊夫在中间窃听到密文c(x)也没问题。
  • 7.鲍勃收到密文,用自己的私钥d对密文进行解密d(c(x)),得到爱丽丝撰写的明文x.
  • 8.由于伊夫没有得到鲍勃的私钥d,所以无法得知明文x.
  • 9.如果爱丽丝丢失了她自己撰写的原文x,在没有得到鲍勃的私钥d的情况下,她的处境将等同伊夫,既无法通过鲍勃的公钥c和密文c(x)重新得到原文x.

在正式介绍RSA之前,先介绍一些数学知识。

互质关系

如果两个正整数,除了1之外没有其他公因子,我们称这两个数是互质关系。比如15和32,说明不是质数也可以构成互质关系。

关于互质关系,有以下结论:

  • 任意两个质数构成互质关系,比如13和61.
  • 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如3和10.
  • 如果两个数中,较大的那个数是质数,则两者构成互质关系,比如97和57.
  • 1和任意一个自然数都是互质关系。
  • p是大于1的整数,则p和p-1构成互质关系,比如57和56.
  • p是大于1的奇数,则p和p-2构成互质关系,比如17和15.

欧拉函数

任意给定正整数n,计算在小于等于n的正整数之中,有多少个与n构成互质关系。计算这个值的方法叫做欧拉函数。以φ(n)表示。如φ(8)=4,应为在1到8之中,与8形成互质关系的有1,3,5,7。

φ(n)的计算方法并不复杂,我们就分情况分析。

第一种情况:

如果n=1,则φ(1)=1。应为1与任何(包括自己)都构成互质关系。

第二种情况:

如果n是质数,则φ(n)=n-1。应为质数与每个小于他的数都构成互质关系。

第三种情况:

如果n是质数的某一个次方,即n=p^k(p为质数,k>=1),则

如φ(8)=φ(2^3)=2^3-2^2=4。

这是应为只有当一个数不包含质数p时,才能与n互质。而包含质数p的数一共有p^(k-1)个,即是1*p、2*p、...、p^(k-1)*p。

上面的式子还可以写成:

第四种情况:

n可以分解成两个互质的整数之积。n = p1 * p2

则 φ(n)=φ(p1p2)=φ(p1)φ(p2)

即积的欧拉函数等于各个因子的欧拉函数之积。如:φ(56)=φ(7*8)=φ(7)*φ(8)=6*4=24

第五种情况:

因为任意大于1的整数,都可以写成一系列质数的积。

根据第四条结论

在根据第三条结论

也就等于

比如:

φ(1323)=φ(3^2*7^2)=1323(1-1/3)(1-1/7)=756

欧拉定理

欧拉定理是指:如果两个正整数a和n互质,则n的欧拉函数φ(n)可以让下面的式子成立:

即是a的φ(n)次方减去1,被n整除。比如,3和7互质,φ(7)=6,(3^6-1)/7=104

如果正整数a与质数p互质,应为φ(p)=p-1,所以欧拉函数可写成:

这个就是著名的费马小定理。

模反元素

如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除。

比如:3和11互质,那么3的模反元素是4,应为3*4-1 可以被11整除。4加减11的整数倍数都是3的模反元素。

欧拉定理可以用来证明模反元素必然存在:

可以看到,a的φ(n)-1次方,就是a的模反元素。

RSA算法

RSA算法之一种非对称加密算法。具体的加密工程如下:

依然使用Alice和他的小伙伴来举例子。

假设Alice想通过一个不可靠的媒体接受Bob的一条私人消息,他可以用下面的方式产生一个公钥和私钥。

  • 1. 随意选择两个大的质数p和q,p不等于q,计算N = pq.
  • 2. 根据欧拉函数,求得r=φ(N)=φ(p)φ(q)=(p-1)(q-1)。
  • 3. 选择一个小于r的整数e,是e与r互质。并求得e关于r的模反元素,命名为d。(求d令ed≡1(mod r))。(模反元素存在,当且仅当e与r互质)
  • 4. 将p和q的记录销毁。

其中(N,e)是公钥,(N,d)是私钥。

举个例子:

  • 1. Alice随机选两个不相等的质数61和53,并计算两数的积N=61*53=3233,N的长度就是密钥长度。3233的二进制是110010100001,一共12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,总要的场合是2048位。
  • 2. 计算N的欧拉函数。 φ(N)=(p-1)(q-1)=60*52=3120.
  • 3. Alice 在1到3120上随机选择了一个随机数e=17。
  • 4. 计算e对φ(N)的模反元素d,即时,ed-1=kφ(N)。
  • 即使求解:17x+3120y=1.用扩展欧几里得算法求解。可以算出一组解(x,y)=(2753,-15),即d=2753。

至此完成计算。

其中N=3233,e=17,d=2753。所以公钥就是(N,e)=(3233,17),私钥(N,d)=(3233,2753)。实际应用中公钥和私钥都是采用ASN.1格式表达的。

RSA的可靠性

在RSA私钥和公钥生成的过程中,共出现过p,q,N,φ(N),e,d,其中(N,e组成公钥),其他的都不是公开的,一旦d泄露,就等于私钥泄露。那么能不能根据N,e推导出d呢?

ed ≡ 1(mod φ(N))。只有知道e和φ(N),才能算出d
φ(N)=(p-1)(q-1)。只有知道p和q,才能算出φ(N)
n=pq,只有将n分解才能算出p和q

所以,只有将n质因数分解,才能算出d。也就意味着私钥破译。

但是,大整数的质因数分解是非常困难的。

加密和解密

加密

加密要用到公钥(N,e)。

假设Bob要向Alice发送加密信息m,他就要用Alice的公钥(N,e)对m进行加密。但m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。

所谓加密就是计算下式的c。

m^e ≡ c (mod n)

假设m=65,Alice的公钥(3233,17),所以等式如下:

65^17≡2790(mod 3233)

所以c等于2790,Bob就把2790发给Alice。

解密

Alice收到Bob发来的2790后,就用自己的私钥(3233,2755)进行解密。

 c^d ≡ m (mod n)

也就是c的d次方除以n的余数就是m。

2790^2753 ≡ 65 (mod 3233)

因此得到原文65。

证明

记下来证明为什么用私钥就能解密。就是要证明这个式子:

 c^d ≡ m (mod n)

因为加密规则是:

m^e ≡ c (mod n)

于是,c可以写成:

c = m^e - kn

将c代入要我们要证明的那个解密规则:

 (m^e - kn)^d ≡ m (mod n)

等同于求证:

m^ed ≡ m (mod n)
因为:ed ≡ 1 (mod φ(n))
所以: ed = hφ(n)+1
将ed代入:
m^(hφ(n)+1) ≡ m (mod n)

接下来,分成两种情况证明上面这个式子。

1. 当m与n互质

根据欧拉定理,此时
m^φ(n) ≡ 1 (mod n)
得到:(m^φ(n))^h × m ≡ m (mod n)

由此原始得到证明。

2. 当m与n不是互质时

此时,由于n等于质数p和q的乘积,所以m必然等于kp或kq。

以 m = kp为例,考虑到这时k与q必然互质,则根据欧拉定理,下面的式子成立:

(kp)^q-1 ≡ 1 (mod q)
进一步得到:
[(kp)^(q-1)]^(h(p-1))× kp ≡ kp (mod q)
即:(kp)^ed ≡ kp (mod q)
改写成:(kp)^ed = tq + kp

上式t必然能被p整除,即t=t'p

(kp)^ed = t'pq + kp

因为m=kp,n=pq,所以:

m^ed ≡ m (mod n)

证明完毕。

注:转载自阮一峰老师

  • 36
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: RSA算法是一种非对称加密算法,它由公钥私钥组成。公钥可以用于加密数据,而私钥用于解密加密的数据。 首先,我们需要生成一组RSA公钥私钥。下面是一个使用Python编写的生成公钥私钥的代码示例: ```python from Crypto.PublicKey import RSA # 生成密钥对 key = RSA.generate(2048) # 获取公钥 public_key = key.publickey().export_key() print("公钥:", public_key.decode()) # 获取私钥 private_key = key.export_key() print("私钥:", private_key.decode()) ``` 以上代码使用了Python的`Crypto`库,首先通过`RSA.generate(2048)`生成一个2048位的RSA密钥对,然后通过`key.publickey().export_key()`获得公钥,通过`key.export_key()`获得私钥。 执行以上代码,会打印出生成的公钥私钥。由于密钥长度为2048位,生成的公钥私钥都会比较长。 以上就是求出一组RSA算法公钥私钥的代码示例。通过这组密钥,我们可以使用RSA算法对数据进行加解密操作。 ### 回答2: RSA算法是一种非对称加密算法,其公钥私钥是一对密钥,用于加密和解密数据。 首先,我们需要生成一对RSA密钥对,其中包括公钥私钥。具体代码如下: ```python from Crypto.PublicKey import RSA # 生成RSA密钥对 key = RSA.generate(2048) # 获取公钥私钥 public_key = key.publickey().export_key() private_key = key.export_key() # 将公钥私钥保存到文件 with open('public_key.pem', 'wb') as f: f.write(public_key) with open('private_key.pem', 'wb') as f: f.write(private_key) ``` 上述代码使用了`Crypto`库来生成RSA密钥对,并将公钥私钥保存到了`public_key.pem`和`private_key.pem`文件中。 生成密钥对后,可以使用公钥对数据进行加密私钥对数据进行解密。具体代码如下: ```python from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP # 加载公钥私钥 with open('public_key.pem', 'rb') as f: public_key = RSA.import_key(f.read()) with open('private_key.pem', 'rb') as f: private_key = RSA.import_key(f.read()) # 使用公钥进行加密 data = b'Hello World!' cipher_rsa = PKCS1_OAEP.new(public_key) encrypted_data = cipher_rsa.encrypt(data) # 使用私钥进行解密 cipher_rsa = PKCS1_OAEP.new(private_key) decrypted_data = cipher_rsa.decrypt(encrypted_data) print('原始数据:', data) print('加密后数据:', encrypted_data) print('解密后数据:', decrypted_data) ``` 上述代码中,使用`Crypto`库中的`RSA`模块加载公钥私钥文件,并使用`PKCS1_OAEP`模块对数据进行加密和解密。加密后的数据为`encrypted_data`,解密后的数据为`decrypted_data`。 ### 回答3: RSA算法是一种非对称加密算法,由三个部分组成:公钥私钥和加解密算法。下面是一个简单的Python代码示例来生成RSA公钥私钥: ```python from Crypto.PublicKey import RSA # 生成RSA密钥对,key_size为密钥长度,一般选择1024位或2048位 key = RSA.generate(2048) # 获取公钥私钥 public_key = key.public_key().export_key() private_key = key.export_key() print("公钥:") print(public_key.decode()) print("\n私钥:") print(private_key.decode()) ``` 以上代码使用了Python的`Crypto`库,需要先安装该库才能运行。 运行代码后,会输出生成的RSA公钥私钥RSA公钥可以用于加密数据,私钥则用于解密数据。 需要注意的是,RSA算法的档案中有许多参数,例如模数(n),公钥指数(e),私钥指数(d),指数的选择对于算法的安全性至关重要。以上代码示例生成的RSA密钥对是具有较高安全性的默认参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值