pythonAES256加密

python AES256加密[Python基础]

基础知识

# 在Linux操作系统下,Python3的默认环境编码变为了utf-8编码,所以在编写代码的时候,字符串大部分都是以utf-8处理

UTF-8:

1byte = 8bit

1个英文字符 = 1byte

1个中文字符 = 3byte

128bit = 16byte = 16个英文字符

192bit = 24byte = 24个英文字符

256bit = 32byte = 32个英文字符

AES256概念

AES是一种对称加密算法,对称指加密和解密使用同一个密钥; 256指密钥的长度是256bit,即32个英文字符的长度;密钥的长度决定了AES加密的轮数

AES256加密参数

  • 密钥: 一个32byte的字符串, 常被叫为key
  • 明文: 待加密的字符串;字节长度(按byte计算)必须是16的整数倍,因此,明文加密之前需要被填充
  • 模式: 加密模式,常用的有ECB、CBC;具体含义见参考链接
  • iv 偏移量: CBC模式下需要是16byte字符串; ECB下不需要

参考代码

# -------------------------------

# -*- coding: utf-8 -*-

# @Author:jianghan

# @Time:2020/11/25 14:46

# @File: crypt.py

# Python版本:3.6.8

# -------------------------------

"""

1、 填充字符串和明文字符串最后一位不能相同

2、 字符串编码默认是utf-8, key和iv默认为英文字符;字符串不支持其他编码或key/iv不支持为中文字符

"""

from enum import Enum, unique

from Crypto.Cipher import AES

@unique

class Mode(Enum):

CBC = AES.MODE_CBC

ECB = AES.MODE_ECB

@unique

class Padding(Enum):

""" 定义填充的字符串 """

SPACE = " " # 空格

class AES256Crypto:

def __init__(self, key, mode=Mode.ECB, padding=Padding.SPACE, iv=None):

"""

:param key: 密钥, 32byte 长度字符串

:param mode: 加密模式, 来源 class Mode

:param iv: 16byte 长度字符串

:param padding: 填充的字符串, 来源class Padding

"""

self.padding = self.check_padding(padding)

self.key = self.padding_key(key)

self.iv = self.padding_iv(iv) if iv else None

self.mode = self.check_mode(mode)

def check_mode(self, mode):

""" 核对 mode """

if mode not in Mode.__members__.values():

raise Exception(f"mode {mode} not allowed!")

if mode == Mode.CBC and not self.iv:

raise Exception(f"iv is required")

return mode

def check_padding(self, padding):

""" 核对 padding """

if padding not in Padding.__members__.values():

raise Exception(f"mode {padding} not allowed!")

return padding

def padding_ret_byte(self, text, _len=16):

""" 填充并转成 bytes """

text = text.encode()

remainder = len(text) % _len

remainder = _len if remainder == 0 else remainder

text += (_len - remainder) * self.padding.value.encode()

return text

def padding_iv(self, iv: str):

""" 补全iv 并转成 bytes"""

if len(iv.encode()) > 16:

raise Exception(f"iv {iv} must <= 16bytes")

return self.padding_ret_byte(iv)

def padding_key(self, key: str):

""" 补全key 并转成 bytes """

if len(key.encode()) > 32:

raise Exception(f"key {key} must <= 32bytes")

return self.padding_ret_byte(key, _len=32)

def encrypt(self, text, encode=None):

"""

加密

:param text: 待加密字符串

:param encode: 传入base64里面的方法

:return: 若encode=None则不进行base加密处理,返回bytes类型数据

"""

text = self.padding_ret_byte(text)

# 注意:加密中的和解密中的AES.new()不能使用同一个对象,所以在两处都使用了AES.new()

text = AES.new(key=self.key, mode=self.mode.value, iv=self.iv).encrypt(text)

if encode:

return encode(text).decode()

return text

def decrypt(self, text, decode=None):

""" 解密 """

if decode:

if type(text) == str:

text = text.encode()

text = decode(bytes(text))

else:

if type(text) != bytes:

raise Exception(text)

text = AES.new(key=self.key, mode=self.mode.value, iv=self.iv).decrypt(text)

text = text.strip(self.padding.value.encode())

return text.decode()

使用范例

import json

# 这是一段待加密的字符串

text = "{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}"

key = "t6LtKa3tD5X6qaJ6qOrAW3XmobFrY6ob"

iv = "NjtP47eSECuOm3s6"

aes = AES256Crypto(key, Mode.CBC, Padding.SPACE, iv)

text_1 = aes.encrypt(text)

# b"xe7x1dxeaexffxc7xc2xd7x8cxf6xe7x82ux7fx168xbcx90xadx1ex85Mxcbxb0xb4Hox1bxe4xecx9dx1dxf93xebx9bxe7xa3xdd$x8cEaxabxf7K~x91Hxc3]5xc4x1axd4w[x83xb2"FCx9fx9d"

text_2 = aes.decrypt(text_1)

# "{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}"

import base64

text_3 = aes.encrypt(text, encode=base64.b16encode)

# "E71DEA65FFC7C2D78CF6E782757F1638BC90AD1E854DCBB0B4486F1BE4EC9D1DF933EB9BE7A3DD248C4561ABF74B7E9148C35D35C41AD4775B83B22246439F9D"

text_4 = aes.decrypt(text_3, decode=base64.b16decode)

# "{"upi": "1341343", "overdue": "2020-11-26 00:00:00"}"

参考

  • https://www.sohu.com/a/201169795_466846
  • https://blog.csdn.net/chouzhou9701/article/details/89339625

以上是 pythonAES256加密 的全部内容, 来源链接: utcz.com/z/538028.html

回到顶部