关于加密方式、编码和字符集的说明:
安装库
# 一个Python的加密库,提供了各种加密算法,包括AES。
sudo pip3 install pycrypto
代码实现
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
AES:
AES加密算法的密钥长度必须是16、24或32字节(128、192或256位)。这些长度分别对应AES-128、AES-192和AES-256。16位够用了。
明文的长度必须是AES块大小的整数倍.
IV的长度必须等于AES的块大小.
print(AES.block_size) # 16
"""
from Crypto import Random
from Crypto.Cipher import AES
import base64
class aescrypt():
def __init__(self, key, model, iv, encode_='utf8'):
"""
key : byte string 用于对称加密的密钥。
iv: byte string 用于加密或解密的初始化向量。mode是ECB时忽略IV
"""
self.encode_ = encode_
# key传参不要超过16位,因为它必须是16位,add_to_16方法其实是补充至16的倍数,这里注意下
self.key = self.add_to_16(key)
self.iv = iv
if model == 'ECB':
self.model = AES.MODE_ECB
# 创建一个aes对象,mode默认是ECB
self.aes = AES.new(self.key, mode=AES.MODE_ECB)
elif model == 'CFB':
self.model = AES.MODE_CFB
# 创建一个aes对象
self.aes = AES.new(self.key, mode=AES.MODE_CFB, IV=self.iv)
def add_to_16(self, par):
# 先将字符串类型数据转换成字节型数据,默认按utf-8编码,中文占3个字节(gbk编码占2个字节)
par = par.encode(self.encode_)
# 对字节型数据进行长度判断,如果字节型数据长度不是16倍整数就进行补充
while len(par) % 16 != 0:
par += b'\x00'
return par
def aesencrypt(self, plaintext):
"""
plaintext : byte string
"""
# 将明文补齐为16字节的倍数
text = self.add_to_16(plaintext)
# 调用加密方法,这个方法返回的数据类型是bytes
encrypt_text = self.aes.encrypt(text)
# 返回base64编码后的bytes数据或再进一步进行utf8解码的str数据
# print(encrypt_text.decode(self.encode_)) # 这个直接utf8解码会报错,所以得先进行base64编码
# return base64.encodebytes(encrypt_text)
return base64.encodebytes(encrypt_text).decode(self.encode_).strip()
def aesdecrypt(self, text):
# 先对要解密的文本作对应的处理,这里对应于aesencrypt方法中的加密数据的处理
# text = base64.decodebytes(text)
text = base64.decodebytes(text.encode(self.encode_))
# 即使在__init__方法中已经创建了self.aes对象,但在CFB模式下,每次加密和解密时都需要重新初始化self.aes对象,以确保使用正确的IV。这是因为CFB模式依赖于IV来生成密钥流,而这个密钥流用于加密和解密数据。
if self.model == AES.MODE_CFB:
self.aes = AES.new(self.key, mode=self.model, IV=self.iv)
# 调用解密方法
decrypt_text = self.aes.decrypt(text)
# 解密后的bytes类型还需要解码为str
return decrypt_text.strip(b'\x00').decode(self.encode_)
if __name__ == '__main__':
# 加密
key = 'this is key'
# iv通过方法生成,bytes类型
iv = Random.new().read(AES.block_size)
print(iv)
# 初始化aescrypt类
pr = aescrypt(key, 'CFB', iv)
# 对content加密
content = '我是要加密的内容'
en_text = pr.aesencrypt(content)
print('密文:', en_text)
# 对加密后的密文解密
print('明文:', pr.aesdecrypt(en_text))
"""
b'\xaf\x96\xec\x810x\xa9\xee;\xc0\x82TM\xc5 \x11'
密文: VBmZmgiINYON81jTRceT21h5fseIk5ZDkG0kc/fGHiQ=
明文: 我是要加密的内容
"""
密码学是一个很大很广的方向,我等任重而道远~
推荐博文
字符集(charset)与编码(encoding)区别对比-****博客
字符集和字符编码(Charset & Encoding)-****博客
[一文详解]Base64编码,Url Base64编码,UrlEncode编码,你还傻傻分不清吗?-****博客
python常见的加密方式-****博客
gpg使用方法_gpg -r $user-****博客
openssl ecc和rsa密钥对以及证书生成_openssl生成ecc密钥-****博客