加密方式从密钥是否相同的角度分为对称加密和非对称加密。

对称加密:“加密”和“解密”使用【相同的】密钥。

非对称加密:“加密”和“解密”使用【不相同的】密钥。

非对称加密服务端生成一对密钥(公钥和私钥),将公钥公开给访问者,要求访问者通过公钥来加密,自己通过私钥来解密。

从效率上来讲,对称加密速率快很多,但是密钥的保存和传输的安全性成了很大的风险;而非对称加密只传输公钥,没有私钥是无法解开密文的,所以安全性更高,但是开销更大。

 

现阶段流行的非对称加密是RSA加密,本文主要解释下RSA非对称加密,并用Python做验证。

 

RSA这个缩写很坑,因为对应的不是什么英文单词的意思,而是发明这种算法的三位数序家的首字母(Rivest、Shamir和 Adleman)

1随机生成2个不想等的质数(也叫素数),p和q

2计算n=p*q, n的二进制就是密钥的长度,一般是1024位,重要场合是2048位

3计算欧拉函数N=(p-1)*(q-1)

4随机选择一个整数e,条件是1<e<N,且e与N互质

5计算一个模反元素d,所谓模反元素就是使N/ed取余=1

        简单可以理解为ed=N+1

6 (n,e)封装为公钥,(n,d)封装为私钥

7利用(n,e)公钥进行加密,明文内容是m,加密后密文是c

        (m的e次方)除以n取余,结果为密文c

        换算成公式是c=(m**e)/n取余

8利用(n,d)私钥进行解密

        (c**d)/n取与,结果为解密后的明文

 

下面python做验证,代码如下:


import math
import random

#判断是否为质数
def isPrime(n):
    if n<=1:
        return False
    for i in range(2,int(math.sqrt(n))+1) :
        if n%i==0:
            return False
    return True


#质数100-200间,不需要算太大,只是为了演算
p = random.choice(range(100,200))
#p=61
while not isPrime(p) :
    p = random.choice(range(100, 200))
else:
    print('P: %d' % p);

q = random.choice(range(100,200))
#q=53
while not isPrime(q) or p==q:
    q = random.choice(range(100, 200))
else:
    print('q: %d'% q);

n=p*q
print('n: %d and bin is %s' %(n,bin(n)))

N=(p-1)*(q-1)
print('欧拉函数N=%d' %N)

#保证e也是个质数,就可以保证e与N互质
e=random.choice(range(1,N))
#e=17
while not isPrime(e) :
    e = random.choice(range(1, N))
else:
    print('e: %d' % e);

#计算模反元素d
d=random.choice(range(1,N))
while not ((e*d)%N==1):
    d = random.choice(range(1, N))
else :
    print('模反元素d: %d' % d);

print('Public key is (%d %d), private key is (%d %d)' %(n,e,n,d))
print('----开始对数据进行加密----')
m=random.choice(range(1, 100))
print('加密前明文m=%d' %m)
c=m**e%n
print('加密后密文c=%d' %c)
print('----开始对数据进行解密----')
M=c**d%n
print('解密后明文m=%d' %M)

 

结果如下:

P: 181
q: 179
n: 32399 and bin is 0b111111010001111
欧拉函数N=32040
e: 1153
模反元素d: 6697
Public key is (32399 1153), private key is (32399 6697)
----开始对数据进行加密----
加密前明文m=43
加密后密文c=405
----开始对数据进行解密----
解密后明文m=43

 


注:公钥和私钥只是在应用层面上相对的,你决定不公开的就为私钥,公开的就为公钥,在数学层面上来说 (n,e)(n,d) 是等价的,谁做私钥都可以,用私钥加密的内容用公钥也可以解的开。数字签名就是对方用自己保管的私钥加密,客户端用公钥来解密,来确保签名方的身份。