1、RSA算法的理解:
生成两对密钥(公钥和私钥),一对给发送者(A)使用,一对给接收者(B)使用,加解密需要使用同一对密钥,因此,A需要使用B的公钥进行加密发送消息,B拿到消息后,才可以使用B自己的秘钥进行解密,这样传送的数据是安全的,但C也可能拿以公钥发送消息,所以B可能不知道这个消息是A还是C发的,所以就有了签名的概念。
2、加密,签名的作用:
加密:由第1点得到,B无法准确无法区分发送者的身份。
签名:A自己的密钥对,先把公钥给到B,然后A使用A自己的私钥生成签名,然后B就使用A的公钥进行校验签名。
# 模块安装:pip install pycryptodome
import base64
from Crypto import Random
from Crypto.Hash import SHA256
from Crypto.Cipher import PKCS1_v1_5 as Cipher_PKC
from Crypto.Signature import PKCS1_v1_5 as Signature_PKC
from Crypto.PublicKey import RSA
class HandleRSA():
def create_rsa_key(self):
# 创建RSA密钥 #
# 步骤说明:
# 1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
# 2、生成 1024/2048 位的 RSA 密钥
# 3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
# 4、将私钥写入磁盘的文件。
# 5、调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
# 生成秘钥对实例对象:1024是秘钥的长度
random_gen = Random.new().read
rsa = RSA.generate(1024, random_gen)
private_pem = rsa.exportKey() # Server的秘钥对的生成
with open("server_private.pem", "wb") as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open("server_public.pem", "wb") as f:
f.write(public_pem)
# Client的秘钥对的生成
private_pem = rsa.exportKey()
with open("client_private.pem", "wb") as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open("client_public.pem", "wb") as f:
f.write(public_pem)
# Server使用Client的公钥对内容进行rsa 加密
def encrypt(self, plaintext):
"""
client 公钥进行加密
plaintext:需要加密的明文文本,公钥加密,私钥解密
"""
# 加载公钥
rsa_key = RSA.import_key(open("client_public.pem").read() )
cipher_rsa = Cipher_PKC.new(rsa_key)
en_data = cipher_rsa.encrypt(plaintext.encode("utf-8")) # 加密
base64_text = base64.b64encode(en_data) # base64 进行编码
return base64_text.decode() # 返回字符串
# Client使用自己的私钥对内容进行rsa 解密
def decrypt(self, en_data):
# en_data:加密过后的数据,传进来是一个字符串
base64_data = base64.b64decode(en_data.encode("utf-8")) # base64 解码
private_key = RSA.import_key(open("client_private.pem").read()) # 读取私钥
cipher_rsa = Cipher_PKC.new(private_key)
data = cipher_rsa.decrypt(base64_data,None) # 解密
return data.decode()
# Server使用自己的私钥对内容进行签名
def signature(self,data:str):
"""
RSA私钥签名
:param data: 明文数据
:return: 签名后的字符串sign
"""
private_key = RSA.import_key(open("server_private.pem").read()) # 读取私钥
# 根据SHA256算法处理签名内容data
sha_data= SHA256.new(data.encode("utf-8")) # b类型
# 私钥进行签名
signer = Signature_PKC.new(private_key)
sign = signer.sign(sha_data)
# 将签名后的内容,转换为base64编码
sign_base64 = base64.b64encode(sign)
return sign_base64.decode()
# Client使用Server的公钥对内容进行验签
def verify(self,auth:str,signature:str) -> bool:
"""
RSA公钥验签
:param data: 明文数据,签名之前的数据
:param signature: 接收到的sign签名
:return: 验签结果,布尔值
"""
# 接收到的sign签名 base64解码
sign_data = base64.b64decode(signature.encode("utf-8"))
# 加载公钥
piblic_key = RSA.importKey(open("server_public.pem").read())
# 根据SHA256算法处理签名之前内容data
sha_data = SHA256.new(auth.encode("utf-8")) # b类型
# 验证签名
signer = Signature_PKC.new(piblic_key)
is_verify = signer.verify(sha_data, sign_data)
return is_verify
# 发送者的加密、签名数据
def send_message(self,sign_auth,message):
encryptMessage = self.encrypt(message)
signData = self.signature(sign_auth)
return {'encrypt_message':encryptMessage,"sign":signData}
# 接收者解密、验签数据
def revice_message(self,sign_auth,signature,encrypt_message):
is_ture = self.verify(auth=sign_auth, signature=signature)
if is_ture == False:
print('非本人操作')
else:
print(self.decrypt(encrypt_message))
return self.decrypt(encrypt_message)
if __name__ == '__main__':
message = '这是加密数据'
mrsa = HandleRSA()
# mrsa.create_rsa_key() # 更新密密钥时才使用
revice_data = mrsa.send_message('zhengqinjie',message)
print(revice_data)
mrsa.revice_message(sign_auth='zhengqinjie1',
signature=revice_data.get('sign'),
encrypt_message=revice_data.get('encrypt_message'))
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
class EncryptDate:
def __init__(self, key):
# 初始化密钥
self.key = key
# 初始化数据块大小
self.length = AES.block_size
# 初始化AES,ECB模式的实例
self.aes = AES.new(self.key.encode("utf-8"), AES.MODE_ECB)
# 截断函数,去除填充的字符
self.unpad = lambda date: date[0:-ord(date[-1])]
def fill_method(self, aes_str):
'''pkcs7补全'''
pad_pkcs7 = pad(aes_str.encode('utf-8'), AES.block_size, style='pkcs7')
return pad_pkcs7
def encrypt(self, encrData):
# 加密函数,使用pkcs7补全
res = self.aes.encrypt(self.fill_method(encrData))
# 转换为base64
msg = str(base64.b64encode(res), encoding="utf-8")
return msg
def decrypt(self, decrData):
# base64解码
res = base64.decodebytes(decrData.encode("utf-8"))
# 解密函数
msg = self.aes.decrypt(res).decode("utf-8")
return self.unpad(msg)
if __name__ == '__main__':
# key的长度需要补长(16倍数),补全方式根据情况而定,未补齐会报错
# key字符长度决定加密结果,长度16:加密结果AES(128),长度32:结果就是AES(256)
eg = EncryptDate("asdfghjklqwertyu")
# 加密字符串长同样需要16倍数:代码中pad()方法里,帮助实现了补全(补全方式就是pkcs7)
en = eg.encrypt("测试数据")
de = eg.decrypt(en)
print(f"加密结果:{en}")
print(f"解密结果:{de}")
import hashlib
m = hashlib.md5()
text = '123'
m.update(text.encode('utf-8'))
print(m.hexdigest())