楔子
对称加密
优点:计算量小、加密速度快、加密效率高;
缺点:密钥需要传递,难以确保密钥安全性。缺乏签名功能,不能核对发信人身份;
非对称加密
在对称加密中,密钥(也就是使用的加密算法,如发电报时的密码本、小人和英文字符的对应关系)的保密性至关重要。战争时期,电报密码本需要通过人工渠道传递,这样发报双方才能放心地使用。
但在如今的网络通信中,显然不可能再使用人工渠道的方式来传递密钥,只有通过网络来传递才高效快捷。这样就有了一个矛盾:密钥是用来保证网络传输安全的,这个对于网络安全至关重要的密钥又需要网络来传递给对方。
保存密钥最安全的方式就是不告诉任何人,不进行传递,但对称加密中,解密方必须要得到对应的密钥,这就又要求密钥必须进行传递,可一旦传递密钥就有丢失的风险。这个"鸡生蛋、蛋生鸡"的问题一直困扰着人们,直到出现了一种算法,这套算法生成的密钥分为两个部分:公钥和私钥。
这个一分为二的密钥对有如下特点:
公钥和私钥是一个算法中两个不同、但内在又相关联的参数集合,同时生成,但可以独立使用;
公钥加密的数据只有对应的私钥才可以解密(公钥加密后公钥也不能解密);
私钥加密的数据也只有对应的公钥才可以解密;
RSA 算法概述
对称加密的模式很好理解,但非对称加密算法的上述特点却让我们感觉很神奇,下面就来简单看看,上述这些特点在数学上是怎样实现的吧。在非对称加密算法中 RSA 是使用最广泛的一种,我们就以 RSA 为例,一会儿再介绍怎么用 Python 实现它。
RSA 算法是 1977 年由共同在麻省理工学院工作的罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA 就是他们三人姓氏开头字母拼在一起组成的。
RSA 加密利用了"单向函数"正向求解很简单,反向求解很复杂的特性。思想如下:
p1*p2 = n,已知 p1、p2 求 n 简单,已知 n 求 p1、p2 很难;
(m^e) % n = c,已知 m、e、n 求 c 简单,已知 e、n、c 求 m 很难;
RSA 算法的安全性基于 RSA 问题的困难性,也就是基于大整数因子分解的困难性上。这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长 RSA 密钥是 768 个二进制位。
也就是说,长度超过 768 位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024 位的 RSA 密钥基本安全,2048 位的密钥极其安全。
非对称加密的算法比对称加密要复杂且耗时,位数越多越耗时。因此在实际使用中,一般是先用非对称加密过程传递对称加密的密钥,之后再使用对称加密来保证后续的通信,这样安全性与速度就可以达到一个平衡,HTTPS 所使用的就是这种方式。
Python 实现 RSA
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii
def generate_keys():
# 生成长度为 2048 的秘钥
key = RSA.generate(2048)
# 生成公钥
private_key = key.export_key()
# 生成私钥
public_key = key.publickey().export_key()
return private_key, public_key
def encrypt_message(public_key, message):
cipher = PKCS1_OAEP.new(RSA.import_key(public_key))
# 使用公钥加密,得到密文(bytes 对象)
encrypted_message = cipher.encrypt(message.encode())
# 一般会转成十六进制进行传输
return binascii.hexlify(encrypted_message).decode()
def decrypt_message(private_key, encrypted_message):
cipher = PKCS1_OAEP.new(RSA.import_key(private_key))
# 解密
decrypted_message = cipher.decrypt(
binascii.unhexlify(encrypted_message)
)
return decrypted_message.decode()
# 生成密钥
private_key, public_key = generate_keys()
message = "高老师总能分享出好东西"
# 使用公钥加密
encrypted = encrypt_message(public_key, message)
print(encrypted)
"""
41bc8709cb82e1f9a13d18f101538c536f760210c11···
"""
print(len(encrypted))
"""
512
"""
# 使用私钥解密
decrypted = decrypt_message(private_key, encrypted)
print(decrypted)
"""
高老师总能分享出好东西
"""
以上就是使用 Python 实现 RSA 算法。