国庆长假之真正搞懂非对称加密算法
Posted 汪院长
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了国庆长假之真正搞懂非对称加密算法相关的知识,希望对你有一定的参考价值。
之前提到面试一些大学的硕士生时发现他们太缺乏知其所以然的欲望和能力了。有个据称搞安全系统的,竟然不知道RSA算法原理。我呢,好歹知道,利用了大数因式分解十分困难,但也不知道具体什么情况。
这两天看《数论概论》,终于搞明白了,麻利地手动写了个出来。代码在github.com/tiehexue/rsa
一,加密过程
我向世界公布自己的公匙,就两个数字m和k,比如m=30796045883, k=48611。假如有人要一串私信给我,比如银行密码x=123456。所谓加密很简单,计算x^k mod (m) = y,y可以通过非安全线路,乃至公开渠道发给我。只有我能从y中还原出x。
x^k mod (m) = y的含义是x的k次方除于m的余数。小伙伴肯定会想实际应用里m, k都很大,这个计算量很大吧?确实很大。。。如果真的先把幂算出来,再做除法的话。。。这个时候,数论就大派用场了。
数论里有个逐次平方法,专门抄近路计算幂模。下面要开始展示魔法了:计算7^327 mod(853)。
7^1 = 7 = 7 mod(853)
7^2 = (7^1)^2 = 7^2 = 49 = 49 mod(853)
7^4 = (7^2)^2 = 49^2 = 2401 = 695 mod(853)
7^8 = (7^4)^2 = 695^2 = 483025 = 227 mod(853)
以此类推。大家发现没?后一步是前一步的平方,使用前一步的余数简化,所以叫逐次平方法。
7^327 = 7^256 * 7^64 * 7^4 * 7^2 * 7^1 = 298 * 123 * 695 * 49 * 7 mod(853)。
这样,就把一个计算量超级大的任务简化成naive任务。把这个步骤写成python程序,当然也要花点脑子。正当我焦头烂额之时,发现python自带的pow(x, k, m)函数可以直接计算,速度奇快无比。所以加密过程一行python代码搞定,如下:
过于简单,参数integers是一个整数list
二,解密过程
聪明如你肯定想到了,解密就是解方程x^k = y mod(m)。数论告诉我们解这个方程需要三步:
1)求出φ(m)。φ(m)叫欧拉函数,指小于m且和m互素的数的个数。如计算φ(6),把1到6-1的数挨个筛选和6的最大公约数为1,只有1, 5符合。所以φ(6) = 2。这个函数有个重要的特点φ(mn)=φ(m)φ(n),如果m和n互素。
2)求方程k*u - φ(m)v = 1的正整数u和v。很明显u和v有无穷对,一般取u是最小正整数的那对。这个方程用扩展欧几里得方法求解非常简单。大家搜一搜xgcd就有好多了。
需要注意一般xgcd方法是求au+bv=1,其中a,b都是正整数,所以我改了下,且只返回u。
3)计算y^u mod(m)即为x。这个计算用前面提到的逐次平方法很简单。
奥妙来了,求φ(m)最最最麻烦,m越大越不可能,或者说m大到一定程度就完全不可能了。
三,奥妙所在
非对称加密就在于选取大的m和k,保证对方无法破解,而自己可以很简单的“破解”。奥妙就在于我们知道φ(m)等于多少,毕竟m是我们选的啊!过程如下:
选取两个特别大的素数p和q,m=p*q,φ(m)=φ(p)*φ(q)=(p-1)*(q-1)=m - p - q +1。k取和φ(m)互素的值就行,不一定非得是素数,当然也可以是素数,如k为大于φ(m)的第一个素数。
所以,我们给别人的m和k叫公匙,自己留着的p和q为私匙。解密算法也很简单:
注意m和u都是已知的,并不需要解密时求出,所以解密也就一个pow函数.
四,我的代码
大家有兴趣,可以把github.com/tiehexue/rsa下载下去运行下。要用python3.x环境,因为它原生支持unicode。main.py把字符串换成unicode对应的整数(应该都是7位以内整数),以7位对齐,拼接成字符串,再以m-1位分割,变成一个整数list,逐个加密解密。
当我以为,我搞懂了RSA之后,我试图看了一些相关源代码,发现。。。。还是看不懂。。。。可见,一个工业级别的算法实现和其原理还有个几十万里的距离。
祝大家国庆快乐!
以上是关于国庆长假之真正搞懂非对称加密算法的主要内容,如果未能解决你的问题,请参考以下文章