对称加密的加密和解密过程使用同一个密钥,在消息传递中,密钥也会被传来穿去,万一密钥被截获,那就完蛋了。
非对称加密过程中的密钥被分为私钥和公钥:
主要有两个应用场景:加密解密、签名验签。典型的非对称加密算法有RSA。
假设B要和A秘密交流:
此场景主要为了防止中间人截获信息,即使中间人截获到密文,就算他知道A的公钥,由于不知道A的私钥,还是无法知道密文啥意思。
Code Example :
# -*- coding: utf-8 -*-
import base64
from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
def generate_key_pair():
"""
生成私钥公钥
:return:
"""
rsa = RSA.generate(bits=1024, randfunc=Random.new().read)
private_key = rsa.exportKey()
public_key = rsa.publickey().exportKey()
return private_key, public_key
def encrypt(plain_text, public_key):
"""
根据公钥对原文加密
:param plain_text:
:type plain_text: str
:param public_key:
:return:
"""
pk = RSA.importKey(public_key)
cipher = PKCS1_v1_5.new(pk)
cipher_text = base64.b64encode(cipher.encrypt(plain_text.encode('utf-8')))
return cipher_text
def decrypt(cipher_text, private_key):
"""
根据私钥对密文进行解密
:param cipher_text:
:type cipher_text: bytes
:param private_key:
:return:
"""
pk = RSA.importKey(private_key)
cipher = PKCS1_v1_5.new(pk)
text = cipher.decrypt(base64.b64decode(cipher_text), Random.new().read)
return text
if __name__ == '__main__':
text = '我是一个好男人!'
prk, puk = generate_key_pair()
cipher_text = encrypt(text, puk)
plain_text = decrypt(cipher_text, prk).decode('utf-8')
print(plain_text)
Output:
我是一个好男人!
假设B要确定A是A,而不是中间者伪造的:
签名验签是为了解决中间人伪造A与B通信的问题。
Code Example:
# -*- coding: utf-8 -*-
import base64
from Crypto import Random
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
def generate_key_pair():
"""
生成私钥公钥
:return:
"""
rsa = RSA.generate(bits=1024, randfunc=Random.new().read)
private_key = rsa.exportKey()
public_key = rsa.publickey().exportKey()
return private_key, public_key
def sign(message, private_key):
"""
根据私钥加签
:param message:
:type message: str
:param private_key:
:type private_key: bytes
:return:
"""
pk = RSA.importKey(private_key)
signer = PKCS1_v1_5.new(pk)
digest = SHA.new()
digest.update(message.encode('utf-8'))
sign = signer.sign(digest)
signature = base64.b64encode(sign)
return signature
def verify(message, public_key, signature):
"""
根据公钥验签
:param message:
:type message: str
:param public_key:
:type public_key: bytes
:param signature:
:type signature: bytes
:return:
"""
pk = RSA.importKey(public_key)
verifier = PKCS1_v1_5.new(pk)
digest = SHA.new()
digest.update(message.encode('utf-8'))
is_verified = verifier.verify(digest, base64.b64decode(signature))
return is_verified
if __name__ == '__main__':
message = "brown"
private_key, public_key = generate_key_pair()
signature = sign(message, private_key)
print(verify(message, public_key, signature))
Output:
True
见维基百科
RSA加密算法
Ref
Pycrypto与RSA密码技术笔记