目录
- 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的密钥,如果未来它们也被破解了,你只需要增加到更大。