非对称加解密应用广泛 ,它的存在是致力于解决密钥通过公共信道传输这一经典难题 。对称加密有一个天然的缺点 ,就是加密方和解密方都要持有同样的密钥 ,而这个密钥在传递过程中有可能会被截获 ,从而使加解密失效 。难不成还要为密钥的传输再做一次加密?这样不就陷入了死循环?或许有人在想 ,密钥即使被盗取 ,不还有加密算法保证信息安全吗?但任何算法最终都会被破译 ,所以不能依赖算法的复杂度来保证安全 。
可能的解决方案如下:
事先共享密
钥密钥分配中心
Diffie-Hellman密钥交换
非对称加密
非对称加密就是一种广泛应用的加解密技术 。非对称加密需要4个密钥 。通信双方各自准备一对公钥和私钥 。其中公钥是公开的 ,由信息接受方提供给信息发送方 。公钥用来对信息加密 。私钥由信息接受方保留 ,用来解密 。既然公钥是公开的 ,就不存在保密问题 。也就是说非对称加密完全不存在密钥配送问题 。
下面是一个简单的场景:
小明确定了自己的私钥mPrivateKey ,公钥 mPublicKey 。自己保留私钥 ,将公钥mPublicKey发给了小红。
小红确定了自己的私钥hPrivateKey,公钥 hPublicKey 。自己保留私钥 ,将公钥hPublicKey发给了小明 。
小明发送信息“周六早10点智慧谷见 ” ,并且用小红的公钥hPublicKey进行加密。
小红收到信息后用自己的私钥hPrivateKey进行解密 。然后回复 “收到,不要迟到 ” 并用小明的公钥mPublicKey加密 。
小明收到信息后用自己的私钥mPrivateKey进行解密 。
由于非对称密钥的特点 ,没有私钥就无法解密配对的公钥加密的信息 ,所以小明不担心自己公钥的任意发布 、复制 。同一公钥无法对此公钥加密的信息解密 。所以 ,问题就变成了 ,只要保存好私钥就可以保证数据传输的安全 ,而私钥不需要在公共信息网络上传递 ,安全性是有基本保障的 。
RSA是1977年由罗纳德·李维斯特(Ron Rivest) 、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的 。RSA就是他们三人姓氏开头字母拼在一起组成的 。RSA是现在使用最为广泛的非对称加密算法 。其原理本文不再赘述 ,毕竟本系列的文章重在实用 。而一旦某一天发现了快速做质因数分解的算法 ,那么RSA就不再安全 。
需要注意的是:
非对称加密的处理速度只有对称加密的几百分之一 。不适合对很长的消息做加密。
1024bit的RSA不应该再被新的应用使用 。至少要2048bit的RSA 。
RSA解决了密码配送问题 ,但是效率更低。所以有些时候 ,根据需求可能会配合使用对称和非对称加密 ,形成混合密码系统 ,各取所长 。
下面使用RSA进行数据加解密,先安装必要的模块:
生成密钥对的代码如下:
from Crypto import Random
from Crypto.PublicKey import RSA
random_generator = Random.new().read
rsa = RSA.generate(2048, random_generator)
# 生成私钥
private_key = rsa.exportKey()
print(private_key.decode(utf-8))
# 生成公钥
public_key = rsa.publickey().exportKey()
print(public_key.decode(utf-8))
with open(demo_private_key.pem, wb)as f:
f.write(private_key)
with open(demo_public_key.pem, wb)as f:
f.write(public_key)
也可以直接使用命令生成密钥对:
openssl genrsa -out rsa_private_key.pem 1024
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
将公钥文件通过电邮 、QQ 、微信等各种通信方式发送给对方 。此时就具备了相互加密通信的可能性 。
以下代码演示了发送的过程:
import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
def get_key(key_file):
with open(key_file) as f:
data = f.read()
key = RSA.importKey(data)
return key
def encrypt_data(msg,key):
cipher = PKCS1_cipher.new(key)
encrypt_text = base64.b64encode(cipher.encrypt(bytes(msg.encode("utf8"))))
return encrypt_text.decode(utf-8)
public_key = get_key(demo_public_key.pem)
encryptedmsg = encrypt_data("hello,tiangong",public_key)
print(encryptedmsg)
with open("encryptmsg.txt", "w", encoding=utf-8) as output_file:
output_file.write(encryptedmsg)
以上代码将明文“hello,tiangong ”通过公钥变换成为密文 ,并且保存在文件encryptmsg.txt 。
内容如下所示:
jFabADeOZOx44R73gUvD9KwKy7nmhzf4fMeP2YBo0ff2DCv/B/2jYD2s6n0p8El2Nt/bnLdGAPKhC/HCv6AzNDG2bjSDLjn9Uy+aWe5h568Z4cPzzmlkIDbOwjCv1VMXaonV28vLW1mznbVLDSOT0Qd13D3KcaoZLRZRzvhyUAe52Yuizi3wfrhBrnfEXdtZzIA5FSRauxT77l/d81RmMbbQk+uN+E8aC3XwJOHfEGhvimU9gcv2NVyh4AI1Gqjfq61KbS/I4Iwo2knHnHHssGLeO6jxk/5JkNw7I8PO+qc27KdF3Ye4uQ+Woy0RoJ6LyFi41wJjs9mk8YJu9DHevg==
我们假设发送方通过各种方式(socket 、电邮 、微信等)将密文内容发送给了接收者 ,接收者使用自己的私钥进行解密 。
其代码如下:
import base64
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
from Crypto.Signature import PKCS1_v1_5 as PKCS1_signature
from Crypto.Cipher import PKCS1_v1_5 as PKCS1_cipher
def get_key(key_file):
with open(key_file) as f:
data = f.read()
key = RSA.importKey(data)
return key
def decrypt_data(encrypt_msg,key):
cipher = PKCS1_cipher.new(key)
back_text = cipher.decrypt(base64.b64decode(encrypt_msg), 0)
return back_text.decode(utf-8)
with open("encryptmsg.txt", "r", encoding=utf-8) as output_file:
encryptedmsg = output_file.read()
private_key = get_key(demo_private_key.pem)
plainmsg = decrypt_data(encryptedmsg,private_key)
print(plainmsg)
运行后即可解出密文 。以上就是一个单向加解密的完整过程 。
声明:本站所有文章,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。