密码学算法主要分为两种:对称加密和非对称加密。
对称加密就是使用了一样的密钥来加密,需要在只有通信的双方知道密钥的情况下才安全。
在非对称加密算法中,有公钥和私钥两种密钥,其中,公钥是公开的,不需要保密,私钥由个人持有,必须妥善保管和注意保密。加密和解密使用两种不同的密钥,用公钥加密,只有私钥能解密,用私钥加密,只有公钥能解密。RSA就是一种常见的,应用很广的非对称加密算法。
A往B发送消息,A用B的公钥把消息加密,只有B的私钥能解密。然后A把加密后的消息发送给B,B用自己的私钥解密就能看到了,途中没有别人可以破解消息,因为别人只有B的公钥。然后B用自己的私钥加密消息,回复给A,A用B的公钥解密读取回复。
但是这样真的安全吗?如果传输过程中消息被人修改了怎么办?如果A加密使用的公钥不一定是B的公钥呢,只是他以为是B的公钥。
上面的问题可以用数字签名和数字证书解决。
数字签名可以解决消息被人修改的问题,数字签名是一个hash算法,A把要发送的消息通过hash算法计算出一个hash值,当做摘要,和消息一起传送,B把消息hash之后得到另一个摘要,是否和A传送过来的摘要相同。如果担心消息和hash摘要都被修改,可以把hash摘要用B的公钥加密,就不怕别人改了。
数字证书可以解决这个公钥是不是B的公钥,数字证书通过权威机构-证书管理机构发放的证书,如同现实中的身份证一样,是证明这个公钥是某人的,数字证书会把这个人的公钥,姓名,证书机构名称,有效期放在一起。
这样A就可以先请求B的公钥,然后B把数字证书给A看,就证明这个是B的公钥,A再拿这个B的公钥去发送消息。但是证书也可以伪造,中途被拦截了,修改成C的公钥,以及B的名字,这怎么办呢?
所以在证书机构办颁发证书的时候,会用数字签名给证书内容做个摘要,然后用机构的私钥加密这个摘要,这样就不怕别人篡改造假证书了。
现在的https协议就是基于非对称加密技术的,首先客户端往服务器发起加密请求,于是服务器会用自己的私钥加密网页,然后连同自己的数字证书(这个证书里包含证书颁发机构做的签名),然后客户端浏览器会查看操作系统认证的受信任的证书颁发机构查找公钥,验证证书是否被篡改,如果被篡改会发出警告。如果查找不到受信任的证书颁发机构,浏览器也会发出警告。
什么时候用公钥加密什么时候用私钥加密呢?我觉得是当你的消息不想让接收者意外的人看到的时候,就用对方的公钥加密。当你需要证明这个消息是你发出的,但是怕被篡改的时候,就用自己的私钥加密签名,然后附上自己的数字证书(包含公钥)。
比如区块链中,为什么说掌握了私钥就掌握了这些币呢,因为你要使用这些币进行交易,你就必须要用你的私钥来加密这条交易信息的摘要,然后别人用你的公钥来解密你的摘要,再进行SHA256哈希你的交易信息,证明这笔交易确实是你发出的。
RSA是最流行的非对称加密技术,只要加密的越长,就越难以破解,因为没有可靠的破解方法。RSA的核心是欧拉定理,证明在之后给出。
RSA算法的主要过程:
我们来看下RSA到底会不会被破解,你目前已知的是 (n,e) ( n , e ) ,想要知道 m m 就得知道 d d ,想要知道 d d 就得知道 ϕ(n) ϕ ( n ) ,想要知道 ϕ(n) ϕ ( n ) 就得知道 pq p q ,想要知道 pq p q ,就得把 n n 给分解质因数,但是目前并没有非常有效的分解质因数的方法,只能穷举,所以只需要你的 pq p q 越大,这个算法就越靠谱。
首先求解欧拉函数,要知道欧拉函数是积性函数,比如 n=pk11pk22…pkmm n = p 1 k 1 p 2 k 2 … p m k m
欧拉函数求出来了,那我们来证明欧拉定理,对于一个正整数 n n ,它的剩余系为 Sn={a1,a2,…,aϕ(n)} S n = { a 1 , a 2 , … , a ϕ ( n ) } ,那么对于一个和 n n 互质的数 b b 来说,这样一个集合 Tn={ba1,ba2,…,baϕ(n)} T n = { b a 1 , b a 2 , … , b a ϕ ( n ) } ,有 Sn=Tn S n = T n
那么两个集合里的所有数字的乘积应该是相等的,有 bϕ(n)∏ϕ(n)i=1ai=∏ϕ(n)i=1aimodn b ϕ ( n ) ∏ i = 1 ϕ ( n ) a i = ∏ i = 1 ϕ ( n ) a i mod n ,所以可以得到 bϕ(n)≡1modn b ϕ ( n ) ≡ 1 mod n
中国剩余定理主要是类似由一个故事得来的,相信大家都听过,就不说了。
中国剩余定理(CRT)主要是给多个同余方程,求解答案,如下:
所以可以得到一个解 x=∑ki=1aiMiM−1i x = ∑ i = 1 k a i M i M i − 1
普通的欧几里德很简单吧,应该大家都会,所以现在我们推导一下扩展欧几里德。
扩展欧几里德也叫裴蜀定理,形式是 ax+by=c a x + b y = c ,求 x,y x , y 的通解,其中 c=k×gcd(a,b) c = k × g c d ( a , b )
所以我们可以首先求解 ax+by=gcd(a,b) a x + b y = g c d ( a , b )
有下面两个式子 :
所以得到结论 x1=y2,y1=x2−[ab]y2 x 1 = y 2 , y 1 = x 2 − [ a b ] y 2
当欧几里德到最后一步的时候 b=0,ax=gcd(a,0)=a,x=1,y=0 b = 0 , a x = g c d ( a , 0 ) = a , x = 1 , y = 0 即可,所以可以用递归 实现扩展欧几里德,下面是代码实现。(扩展欧几里德的其他应用,可以参考后面链接)
void exgcd(int a, int b, int d, int &x, int &y){
if(b == 0){
d=a;
x=1;
y=0;
}
else{
exgcd(b, a%b, d, x, y);
int k = x;
x = y;
y = k - a/b*y;
}
}
密码学哈希算法主要是有MD5,以及SHA等算法,特点是不可逆以及没有 冲突(冲突概率极小),和普通的哈希算法很类似,和内存中的哈希表不同。
RSA参考博客RSA算法
中国剩余定理参考David Lin的回答 - 知乎
扩展欧几里德参考欧几里得算法与扩展欧几里得算法_C++