目录
- RSA加密算法
- 非对称加密算法
- 工作原理
- 数学原理
- 因子
- 质数
- 互质
- 互质性质
- 欧拉函数
- 欧拉函数性质
- 同余
- 同余性质
- 欧拉定理
- 费马小定理
- 模反元素
- 欧几里得算法
- 定义
- 计算过程
- 证明
- 扩展欧几里得算法
- 定义
- 计算过程
- 证明
- Python实现
- Java实现
- 确定 n , e , d n,e,d n,e,d
- 加密解密
- 计算过程
- Python实现
- Java实现
- 证明
- 破解私钥
RSA加密算法
RSA加密算法 是一种 非对称加密算法,在公开密钥加密和电子商业中被广泛使用。例如:
- 在HTTPS协议的加密层(SSL/TLS)作为密钥交换的方法
- 支付宝支付API作为签名算法
- 银联支付API作为签名算法
- Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议
非对称加密算法
公开密钥密码学 (英语:Public-key cryptography,也称 非对称式密码学 )是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;一个用作加密,另一个则用作解密。 使用其中一个密钥把明文加密后所得的密文,只能用相对应的另一个密钥才能解密得到原本的明文;甚至连最初用来加密的密钥也不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密; 不同于加密和解密都使用同一个密钥的对称加密。虽然两个密钥在数学上相关,但如果知道了其中一个,并不能凭此计算出另外一个;因此其中一个可以公开,称为公钥,任意向外发布;不公开的密钥为私钥,必须由用户自行严格秘密保管,绝不透过任何途径向任何人提供,也不会透露给被信任的要通信的另一方。
工作原理
本质就是依赖于三个自然数:, 和 构成一个密钥, 和 构成另一个密钥。对于与这两个密钥,无论用哪个密钥加密出来的密文都可以用另一个密钥解开, 所以不必强调哪个用于加密,哪个用于解密,只要把一个公布出去(称为公钥),另一个自己藏着(称为私钥)就行了。
根据这种特性,通常,
- 使用 公钥加密 , 私钥解密 ,实现 加密。
- 使用 私钥加密 , 公钥解密 ,实现 数字签名 。
- 代替 密码散列函数+Token,比如MD5、SHA2,做 消息认证。
(关于加密、数字签名,消息认证可以期待下篇文章。)
关于
- 如何确定这三个自然数?
- 如何进行加密解密?
- 已知公钥如何破解私钥?
我们需要了解RSA加解密的数学原理,主要包括
- 互质
- 欧拉函数
- 同余
- 欧拉定理
- 模反元素
- 扩展欧几里得算法
数学原理
你可以快速浏览这些定理和性质,然后进入下一章节,笔者在下一章节回答上述三个问题的同时,尽可能地将所需定理和性质做出了明确标注,阅读过程中可以随时回过头来确认。
因子
一个整数被另一整数整除,后者即是前者的 因子,如1、2、4、8都为8的因子。
质数
大于1的自然数,除1和本身外没有其他正因子,称为 质数 。
互质
两个自然数,除1以外没有其他公因子,则称它们为 互质 。
互质性质
根据以上定理可以得出以下几个性质(并不止于以下性质)
- 任意两个不相等质数一定互质(因为质数的因子只有1和本身,如果不相等则公因子只有1)
- 1和任意自然数都互质(只有1是公因子)
- 一个数是质数,另一个数只要不是前者的倍数,则二者互质(质数的因子只有1和本身,如果后者的因子不包含这个前者,那么二者公因子只有1)
- 两个数,较大的数是质数,那么二者互质(可由 互质性质3 得到)
- 两个不等质数之 积 的因子有4个,即,1,两个不等质数以及积本身(由 质数定理 和 组合 可以得到)
欧拉函数
我们把用来表示“ 小于或等于的正整数中与互质的数的数目 ”的函数,称为欧拉函数,计作
欧拉函数性质
- 若是质数,那么
由 互质性质4 可得。 - 若,且,是 两个不相等的质数,那么
证明:
- 求,即求:小于等于的的正整数,有多少数与互质
- 逆向思考,可以先求:小于等于的的正整数,有多少数与不互质
- 由于为的质因子,所以,如果一个数不与互质,那么这个数一定是或的整数倍(由 互质性质5 得)
- 由于,所以,中包含,一共个的倍数;同时包含,一共个的倍数
- 又因为是的质因子,所以,是的最小公倍数,即,在小于等于的正整数中不存在的其它公倍数
- 所以,小于等于的的正整数,有个数与不互质
- 所以,小于等于的的正整数,与互质的数有
同余
两个整数,,若它们除以正整数所得的余数相等,则称,对于模同余,记作
同余性质
- 当时,
- 整除性 ,
- 保持基本运算 ,
这性质更可进一步引申成为这样: - 放大缩小底数 ,k为整数,n为正整数,
同余性质3、4 可以根据 同余性质2 整除性来证明。
例如,证明:
其它可同理证明。
同余性质 是证明RSA加解密的关键。
欧拉定理
对任何两个互质的正整数 、,,有
费马小定理
如果n是质数p,那么
由 欧拉函数性质1 可得
模反元素
如果两个正整数和互质,那么一定可以找到整数,使得被整除
此时就是关于的 模反元素。由 欧拉定理 可证,一定存在。
就是关于的 模反元素 。模反元素可以通过 扩展欧几里得算法 求得。
欧几里得算法
定义
又称 辗转相除法 ,是求最大公约数(最大公因子)的算法。两个整数的最大公约数,记作
计算过程
将前两次余数
分别作为被除数
与除数
,得到新的余数
,
递归计算,直到 ,那么此时 最大公约数 为
证明
证明,时,是的 最大公因子 (
- 因为,所以,所以可以被整除,同理(递降归纳)可求所有余数都可以被整除,所以
- 当,有,即整除
- 又当,又因为整除,那么可以整除,同理(递降归纳),可以整除所有余数
- 又因为,所以,此时
- 结论,由于,当时,,所以当时,
扩展欧几里得算法
定义
顾名思义是 欧几里得算法 的扩展。已知整数,扩展欧几里得算法 可以在求得的最大公约数的同时,能找到整数(其中一个很可能是负数),使它们满足 贝祖等式
在欧几里得算法中,我们仅仅利用了每步带余除法所得的余数。扩展欧几里得算法还利用了带余除法所得的商,在辗转相除的同时也能得到 贝祖等式
计算过程
扩展欧几里得算法 在 欧几里得算法 的基础上增加了两个递归等式的计算
递归计算,直到 ,那么此时
证明
证明,(已知条件为上述三等式),使用 完整归纳法
- 当,
- 当,
- 假设成立,那么
所以,满足 贝祖等式。
Python实现
#python3.7
def ext_euclid(a, b):
r0, r1 = a, b
s0, s1 = 1, 0
t0, t1 = 0, 1
if a * b == 0:
raise Exception("a,b must be nonzero!")
while r1 != 0:
q = r0 // r1
r0, r1 = r1, r0 - q * r1
s0, s1 = s1, s0 - q * s1
t0, t1 = t1, t0 - q * t1
return r0, s0, t0
Java实现
public BigInteger[] extEuclid(String a, String b) {
BigInteger r0 = new BigInteger(a), r1 = new BigInteger(b),
s0 = BigInteger.ONE, s1 = BigInteger.ZERO,
t0 = BigInteger.ZERO, t1 = BigInteger.ONE;
if(r0.multiply(r1).equals(BigInteger.ZERO))
throw new IllegalArgumentException("a,b must be nonzero!");
BigInteger q;
BigInteger intermediate;
while (!r1.equals(BigInteger.ZERO)){
BigInteger[] quotientAndRemainder = r0.divideAndRemainder(r1);
q = quotientAndRemainder[0];
r0 = r1;r1 =quotientAndRemainder[1];
intermediate = s0 ;s0 = s1;s1=intermediate.subtract(s1.multiply(q));
intermediate = t0 ;t0 = t1;t1=intermediate.subtract(t1.multiply(q));
}
return new BigInteger[]{r0,s0,t0};
}
确定
- 选择两个 不等质数 ,让。假设,那么
- 由上述 欧拉函数性质2 得,。我们随机选择一个数,保证,同时保证,与互质。那么 ,随机选择
- 求关于的 模反元素 ,即, ,
根据 扩展欧几里得算法 可求,
加密解密
计算过程
设 明文
为,密文
为,如果用加密,解密,过程如下:
- 加密公式
- 解密公式
- 已知
明文
为,用加密 - 已知
密文
为,用解密
Python实现
#python3.7 注意,pow()当包含第三个参数时,指数不可为负值
print(pow(38, 57, 391))
print(pow(327, 105, 391))
Java实现
System.out.println(BigInteger.valueOf(38).modPow(BigInteger.valueOf(57), BigInteger.valueOf(391)));
System.out.println(BigInteger.valueOf(327).modPow(BigInteger.valueOf(105), BigInteger.valueOf(391)));
证明
证明,已知加密公式
,证明解密公式
成立。
- 根据已知条件,得出公式
- 当互质,(根据 欧拉定理)
- 当不互质
- 因为不互质,所以,除1外有额外公共因子(根据 互质 定理)
- 因为,所以有四个因子,(根据 互质性质5)
- 又因为,所以 或
- 假设,此时互质(根据 互质性质4 ),同时因为互质,所以互质。
- 由4,5,6可得
破解私钥
假如我们已知公钥,所谓破解私钥,就是通过,求出。
已知,所以要求,先求,
加密时我们通过计算出,而破解时我们根本不知道,需要通过对进行 因数分解 求出。
所以,要破解私钥,就要对进行 因数分解 ,越大破解越困难。
目前已破解748-bit的密钥,如果你觉得1024-bit还不够安全,你可以使用2048-bit的密钥,如果未来它们也被破解了,你只需要增加到更大。