密码学:非对称加密之 RSA 算法

所谓非对称加密算法就是加密和解密采用不同的密钥,加密时用公钥,解密时用私钥。而在当今互联网世界,使用最广泛的非对称加密算法非 RSA 莫属,我们熟知的支付宝、微信支付等支付工具、HTTPS 协议等无一不在使用 RSA。
RSA算法之所以被广泛使用,究其原因就在于它的极高的安全性,在提升安全性的情况下,它的性能就相对于对称加密算法如 AES要差很多。因此,它适用于一些对安全性要求较高的功能。

RSA 底层原理

公钥和私钥的产生

根据 RSA 算法原理,其公钥和私钥产生的步骤如下:

随机选择两个不同的大质数 p 和 q,计算 n=p*q。(这里的大质数要足够大,大到无法想象)
根据欧拉函数,计算 φ = (p - 1) * (q - 1)。
选择一个小于φ的整数 e,使得 e 和φ互质(即 e 和φ的公约数为 1),并求出 e 关于φ的模反元素 d,(ed - 1) mod φ = 0(所谓模反元素,其概念是如果两个正整数 a 和 n 互质,那么一定可以找到整数 b,使得 ab - 1 被 n 整除)。
销毁 p 和 q。
此时,公钥为(n,e),私钥为(n,d)。

RSA 的数学知识

欧拉函数

欧拉函数是这样定义的,它是小于或等于 n 的正整数中与 n 互质的数的数目φ (n),如 n=9,小于等于 9 的正整数中,可与之互质的数有 1、2、4、5、7、8,因而φ (n)=6。

RSA 算法中,利用了素数的分解,因而关于欧拉函数,我们只需要考虑 n 为质数的情形,如 n=7。由于质数与小于它的所有正整数都构成互质关系,因此φ (n) = n-1。在上述公钥和私钥产生的第二步,φ =(p - 1)* (q - 1),它就是由两个欧拉函数值乘积构成。

欧几里得算法

欧几里得算法就是用于求两个正整数的最大公约数(如果最大公约数为 1 则两数互质)的算法,又叫辗转相除法。
最大公约就是由上一步的除数除以余数,一直计算下去,直到余数为 0 结束,其最大公约数就是最后一个算式的除数。因此,利用欧几里得算法可以轻松找到两个互质的正整数。

欧几里得算法的编程语言实现:

Python 具体代码如下:

def gcd(a,b):
    if a % b == 0:
        return b
    r = a % b
    return gcd(b,r)

扩展欧几里得元素求模反元素 d。

私钥有一个重要的元素是模反元素,我们用字母 d 表示,公式为(ed - 1) mod φ = 0,上述公式可以转化为 ed mod φ = 1,亦即 ed - φ * k = 1(其中 k 为正整数)。一般地,e 和 φ都是已知的,通过扩展欧几里得算法就可以求得 d。

设 e = 17 , φ = 2020,则上述公式可以写成 17 * d - 2020 * k = 1。按照欧几里得算法有以下结论:

2020 % 17 = 14,将 2020 替换成 14,有 17 * d - 14 * k = 1。
17 % 14 = 3,将 17 替换成 3,有 3 * d - 14 * k = 1。
14 % 3 = 2,将 14 替换成 2,有 3 * d - 2 * k = 1。
3 % 2 = 1,将 3 替换成 1,有 1 * d - 2 * k = 1。
当 d 的系数为 1 时,结束欧几里得算法,然后回代:

令 k = 0,代入 4 式有:d = 1。
将 d = 1,代入 3 式有:k = 1。
将 k = 1,代入 2 式有:d = 5。
将 d = 5,代入 1 式有:k = 6。
将 k = 6,代入 17 * d - 2020 * k = 1 中有:d = 713。
此时就可求得模反元素 d = 713。

按照上述思路,我们同样可以通过代码表示:

def exgcd(e,phi):
    if phi == 0:
        x = 1
        y = 0
        return x,y
    d,y = exgcd(phi,e % phi)
    return y,d-e//phi*y

RSA 加密和解密
设有正整数 m,公钥为 (n,e),则加密公式为:c=m 的 e 次方再模 n,用 Python 代码可表示为:

c = pow(m,e,n)

设有加密后的正整数 c,私钥为 (n,d),则解密公式为:m=c 的 d 次方再模 n,用 Python 代码可表示为:

m = pow(c,d,n)

RSA 的破解

我们知道,RSA 的公钥其实就是 (n,e),而 n 是两个素数的乘积,因此要破解 RSA,则需将大整数 n 分解成两个素数的乘积。一般的整数比如 15,我们很快就能算出它可以由素数 3 和 5 相乘得来。但是对于一个足够大的整数呢,当前数学界还没有一个算法可以轻松分解大整数,唯一的办法就是暴力破解。而暴力破解成本过大,目前人类使用超级计算机,已经将大整数的分解计算到了 768 位,也就是说超过 768 位的大整数,我们还是无法破解。

RSA 从 1977 年诞生到现在依然坚不可摧,必然有其强大之处,那就是他的不可破解性,像微信、支付宝这些大企业的 RSA 算法都是 2048 甚至 4096 位的,像这类 RSA 算法现阶段是不可能被破解的。但是还有一些应用的安全意识不高,导致 RSA 算法安全性低下(如采用低于 768 位的公私钥)。接下来,我就给你讲解一下 RSA 的破解思路有哪些,以便你在开发应用时,如果使用了 RSA,可以提升 RSA 的安全性,降低应用风险。

大整数分解
如果你的 RSA 采用了低于 768 位的公私钥(其实 1024 位还是有机会破解,公私钥最好采用 2048 甚至更高位),那么你的 RSA 基本可以百分百破解。下面,我用一个实际的例子来演示如何破解 RSA。

例:设有下列信息

n = 98432079271513130981267919056149161631892822707167177858831841699521774310891
e = 65537
c = 5077560311513279671817430508125151837396585328082180175253360345086848717946

求明文 m。

按照 RSA 原理,首先分解 n 为两个素数的乘积,我们人工分解难度较大,可以通过访问 http://www.factordb.com/ 网站在线分解,然后分别计算φ和 d,最后利用公式 m = pow(c,d,n) 解密。

下面用 Python 给出实现代码。

-- coding:utf8 --

def exgcd(e,phi):
    if phi == 0:
        x = 1
        y = 0
        return x,y
    d,y = exgcd(phi,e%phi)
    return y,d-e//phi*y
n = 98432079271513130981267919056149161631892822707167177858831841699521774310891
e = 65537
c = 5077560311513279671817430508125151837396585328082180175253360345086848717946
p = 302825536744096741518546212761194311477
q = 325045504186436346209877301320131277983
phi = (p - 1) * (q - 1)
d = exgcd(e,phi)
m = pow(c,d[0],n)
print m

模不互质攻击

如果存在两个公钥的 n1 和 n2,且不互质,我们可以直接求 n1 和 n2 的最大公约数,然后可以求出 p 和 q,进而按照前面讲解的方法获得私钥。

p = gcd(n1,n2)
q1 = n1 / p
q2 = n2 / p

共模攻击

当两个用户使用同一个 n,不同的公钥,加密同一明文时即存在共模攻击。

设存在 e1 和 e2,且二者互质,明文为 m,密文则为:

c1 = pow(m,e1,n)
c2 = pow(m,e2,n)
当 c1 和 c2 已知时,就可以恢复出明文 m。

由 e1 和 e2 互质可知,存在两个整数 r 和 s,使得 r * e1 + s * e2 = 1,用扩展欧几里得算法可以算出整数 r 和 s(一正一负),假设 s 为负数,则需求出对应的 c2 对 n 的模反元素 x。

小公钥指数攻击

根据该攻击名称可知,形成该攻击的条件就是公钥指数 e 要足够小。我们可以从小到大枚举 k,依次开 17 次方根,直到开出整数为止,该整数即为明文 m。

因此,我们在实现 RSA 时,公钥指数 e 要尽可能大些,防止被暴力破解,一般设置为 e = 65537。

小结

由于 RSA 算法是由数学家和计算机科学家共同完成的,因此该算法大量运用了数学方法,包括欧拉函数、欧几里得算法等。为了提高 RSA 的安全性,它还利用了大整数的不可分解特性。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值