python 实现aes256加密

作者:姜涵 时间:2021-01-20 22:31:38 

基础知识

# 在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'\xe7\x1d\xeae\xff\xc7\xc2\xd7\x8c\xf6\xe7\x82u\x7f\x168\xbc\x90\xad\x1e\x85M\xcb\xb0\xb4Ho\x1b\xe4\xec\x9d\x1d\xf93\xeb\x9b\xe7\xa3\xdd$\x8cEa\xab\xf7K~\x91H\xc3]5\xc4\x1a\xd4w[\x83\xb2"FC\x9f\x9d'
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.cnblogs.com/jh11200/p/14041249.html

标签:python,aes,256,加密
0
投稿

猜你喜欢

  • JScript RuntimeObject检测全局污染

    2010-09-13 12:26:00
  • 解决Python2.7读写文件中的中文乱码问题

    2023-05-16 11:23:51
  • Go语言的IO库那么多纠结该如何选择

    2023-10-08 07:16:46
  • pycharm中代码回滚到指定版本的两种实现方法(附带截图展示)

    2021-11-26 22:51:18
  • pytorch collate_fn的基础与应用教程

    2021-06-03 02:55:57
  • 三谈Iframe自适应高度

    2010-08-03 13:04:00
  • python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法

    2023-11-13 13:35:51
  • Webpack4 使用Babel处理ES6语法的方法示例

    2023-08-30 08:12:37
  • python+selenium实现12306模拟登录的步骤

    2021-06-18 15:32:56
  • Django如何与Ajax交互

    2023-05-09 12:53:11
  • Go语言设计实现在任务栏里提醒你喝水的兔子

    2023-07-15 04:24:22
  • 这么多的 Oracle 性能工具

    2008-06-04 11:20:00
  • pythotn条件分支与循环详解(3)

    2023-11-14 01:35:06
  • Tensorflow 自定义loss的情况下初始化部分变量方式

    2023-02-26 22:43:39
  • python绘制神器五角星+小黄人+樱花

    2022-02-11 03:45:27
  • python中使用smtplib和email模块发送邮件实例

    2022-09-16 05:37:23
  • 工程师必须了解的LRU缓存淘汰算法以及python实现过程

    2023-05-22 22:46:00
  • 脚本测试postman快速导出python接口测试过程示例

    2022-11-03 09:28:10
  • 微软建议的ASP性能优化28条守则(3)

    2008-02-24 16:30:00
  • Go语言流程控制详情

    2023-10-16 13:16:24
  • asp之家 网络编程 m.aspxhome.com