python 實現(xiàn)aes256加密
基礎(chǔ)知識
# 在Linux操作系統(tǒng)下,Python3的默認(rèn)環(huán)境編碼變?yōu)榱藆tf-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加密的輪數(shù)
AES256加密參數(shù)
- 密鑰: 一個32byte的字符串, 常被叫為key
- 明文: 待加密的字符串;字節(jié)長度(按byte計算)必須是16的整數(shù)倍,因此,明文加密之前需要被填充
- 模式: 加密模式,常用的有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、 字符串編碼默認(rèn)是utf-8, key和iv默認(rèn)為英文字符;字符串不支持其他編碼或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): """ 填充并轉(zhuǎn)成 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 并轉(zhuǎn)成 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 并轉(zhuǎn)成 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則不進(jìn)行base加密處理,返回bytes類型數(shù)據(jù) """ 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"}'
以上就是python 實現(xiàn)aes256加密的詳細(xì)內(nèi)容,更多關(guān)于python aes256加密的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Python 2.6 升級至 Python 2.7 的實踐心得
本篇文章主要介紹了詳解Python 2.6 升級至 Python 2.7 的實踐心得,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04解決python3讀取Python2存儲的pickle文件問題
今天小編就為大家分享一篇解決python3讀取Python2存儲的pickle文件問題,具有很好的參考價值。希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10詳盡講述用Python的Django框架測試驅(qū)動開發(fā)的教程
這篇文章主要介紹了詳盡講述用Python的Django框架測試驅(qū)動開發(fā)的教程,主要使用TDD工具,全文介紹非常詳細(xì),需要的朋友可以參考下2015-04-04在Python的Flask框架中實現(xiàn)全文搜索功能
這篇文章主要介紹了在Python的Flask框架中實現(xiàn)全文搜索功能,這個基本的web功能實現(xiàn)起來非常簡單,需要的朋友可以參考下2015-04-04Django使用HTTP協(xié)議向服務(wù)器傳參方式小結(jié)
本文主要介紹了Django使用HTTP協(xié)議向服務(wù)器傳參方式小結(jié),用戶發(fā)送請求時攜帶的參數(shù)后端需要使用,而不同的發(fā)送參數(shù)的方式對應(yīng)了不同的提取參數(shù)的方式,本文就詳細(xì)的介紹一下2021-08-08Python進(jìn)行數(shù)組的排序、倒序、截取方式
這篇文章主要介紹了Python進(jìn)行數(shù)組的排序、倒序、截取方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02