Python - AES SHA1PRNG 加密解密总结

Max.Bai

2020-11

上篇文章是当时研究AES加密的时候的记录,来龙去脉可以取看这篇 python3 - AES 加密实现java中SHA1PRNG 算法

好多人回复并提问,我发现还有必要写这篇做一个总结,并写成了一个开箱即用类,添加了ECB,CBC的加解密,当然也包含SHA1PRNG,如果其他类型可以参照里面代码添加其他加密模式。

加解密的流程总结:

0. 确认加密模式、ECB、CBC等

1. key,看是否需要sha1prng, 看是否需要做padding,cbc的需要16的倍数,所有需要padding为16的倍数,或者你自己的padding方法。

2. 加密内容确认填充模式,被加密内容当为CBC的时候必须16倍数,当然就涉及到了填充模式pkcs5/7, zero deng

3. iv 只有CBC的时候需要, iv必须16倍数,要么填充,要么iv设置成16倍数

4. 确认加密输出格式 base64、hexstr

加密流程:

key --> sha1prng encode | padding | customencode

content --> padding --> transfer to bytes --> encrypt(ECB/CBC/...) --> transfer to format(base64/hexstr)

解密流程:

key --> sha1prng encode|padding|customencode

encrypted(base64/hexstr) --> transfer to bytes --> decrypt(ECB/CBC/...) --> unpadding --> transfer to str

codding by max.bai 2020-11

开箱即用的完整的代码:

包含了ECB、CBC的样例。

# -*- coding: utf-8 -*-"""
AES cryptrequirment mode:
pycryptodomeFor Java SHA1PRNG KEYMax.Bai
2020-11"""
import base64
from Crypto.Util.Padding import pad, unpad
from Crypto.Util.py3compat import bchr, bord
import Crypto.Cipher.AES as AES
import hashlibBS = AES.block_sizeclass AES_Crypt:PADDING_PKCS5 = "PKCS5"PADDING_PKCS7 = "PKCS7"PADDING_ZERO = "ZEROPKCS"NO_PADDING = "NOPKCS"def __init__(self, key: bytes, mode: str = AES.MODE_ECB, padding: str = "NOPKCS") -> None:"""AES cryptEncrypt fllow:key --> sha1prng encode|padding|customencodecontent --> padding --> transfer to bytes --> encrypt(ECB/CBC/...) --> transfer to format(base64/hexstr)Decrypt fllow:key --> sha1prng encode|padding|customencodeencrypted(base64/hexstr) --> transfer to bytes --> decrypt(ECB/CBC/...) --> unpadding --> transfer to strcodding by max.bai 2020-11Args:key (bytes): encrypt key, if mode is CBC, the key must be 16X len.mode (str, optional): AES mode. Defaults to AES.MODE_ECB.padding (str, optional): AES padding mode. Defaults to "NOPKCS"."""self.key = keyself.pkcs = padding@staticmethoddef get_sha1prng_key(key: str, byte_len:int=128) -> bytes:"""encrypt key with SHA1PRNGsame as java AES crypto key generator SHA1PRNGkey: encode/decode keybyte_len: length of key gen,  same as java code kgen.init(128, secureRandom);default is 128"""signature = hashlib.sha1(key.encode()).digest()signature = hashlib.sha1(signature).digest()len = int(byte_len/8)return signature[:len]@staticmethoddef padding_pkcs5(value: str) -> bytes:"""padding pkcs5 modeArgs:value (str): need padding dataReturns:bytes: after padding data with bytes type"""padding_len = BS - len(value.encode()) % BSreturn value.encode() + bchr(padding_len) * padding_len@staticmethoddef padding_zero(value: str) -> bytes:"""padding with zeroArgs:value (str): need padding dataReturns:bytes: after padding data with zero with bytes type"""while len(value) % 16 != 0:value += "\0"return str.encode(value)@staticmethoddef unpadding_pkcs5(value: bytes) -> bytes:"""unpadding pkcs5 modeArgs:value (bytes): need unpadding dataReturns:bytes: after unpadding"""padding_len = bord(value[-1])return value[:-padding_len]@staticmethoddef unpadding_zero(value: bytes) -> bytes:"""unpadding zero modeArgs:value (bytes): need unpadding dataReturns:bytes: after unpadding"""return value@staticmethoddef bytes_to_base64(value: bytes) -> str:"""bytes transfer to base64 format"""return base64.b64encode(value).decode()@staticmethoddef base64_to_bytes(value: str) -> bytes:"""base64 transfer to bytes"""return base64.b64decode(value)@staticmethoddef bytes_to_hex(value: bytes) -> str:"""bytes transfer to hex str format"""return value.hex().upper()def _get_padding_value(self, content: str) -> bytes:"""get padding value from padding dataOnly add pkcs5, pkcs7, zero, nopadding mode,you can add your padding mode and unpadding mode in thissectionArgs:content (str): need padding dataRaises:Exception: no supporting padding mode Returns:bytes: padded data"""if self.pkcs == AES_Crypt.PADDING_PKCS5:padding_value = self.padding_pkcs5(content)elif self.pkcs == AES_Crypt.PADDING_PKCS7:padding_value = pad(content.encode(), BS, style='pkcs7')elif self.pkcs == AES_Crypt.PADDING_ZERO:padding_value = self.padding_zero(content)elif self.pkcs == AES_Crypt.NO_PADDING:padding_value = str.encode(content)else:raise Exception("No supporting padding mode! Not implation padding mode!")return padding_valuedef _get_unpadding_value(self, content: bytes) -> bytes:"""get unpadding value from padded dataOnly add pkcs5, pkcs7, zero, nopadding mode,you can add your padding mode and unpadding mode in thissectionArgs:content (str): need unpadding dataRaises:Exception: no supporting padding mode Returns:bytes: unpadded data"""if self.pkcs == AES_Crypt.PADDING_PKCS5:unpadding_value = self.unpadding_pkcs5(content)elif self.pkcs == AES_Crypt.PADDING_PKCS7:unpadding_value = unpad(content, BS, style='pkcs7')elif self.pkcs == AES_Crypt.PADDING_ZERO:unpadding_value = self.unpadding_zero(content)elif self.pkcs == AES_Crypt.NO_PADDING:unpadding_value = contentelse:raise Exception("No supporting padding mode! Not implation padding mode!")return unpadding_value# ECB encryptdef ECB_encrypt_to_bytes(self, content: str) -> bytes:"""ECB encrypt to bytes typeArgs:content (str): need encrypt contentReturns:bytes: encrypted content with bytes type"""cryptor = AES.new(self.key, AES.MODE_ECB)padding_value = self._get_padding_value(content)ciphertext = cryptor.encrypt(padding_value)return ciphertextdef ECB_encrypt_to_base64(self, content: str) -> str:"""ECB encrypt to base64 formatArgs:content (str): need encrypt contentReturns:str: encrypted content with base64 format"""ciphertext = self.ECB_encrypt_to_bytes(content)return self.bytes_to_base64(ciphertext)def ECB_encrypt_to_hex(self, content: str) -> str:"""ECB encrypt to hex str formatArgs:content (str): need encrypt contentReturns:str: encrypted content with hex str format"""ciphertext = self.ECB_encrypt_to_bytes(content)return self.bytes_to_hex(ciphertext)# ECB decryptdef ECB_decrypt_from_bytes(self, ciphertext: bytes) -> bytes:"""ECB decrypt from bytes typeArgs:ciphertext (bytes): need decrypt dataReturns:bytes: decrypted content with bytes type"""cryptor = AES.new(self.key, AES.MODE_ECB)content = cryptor.decrypt(ciphertext)unpadding_value = self._get_unpadding_value(content)return unpadding_valuedef ECB_decrypt_from_base64(self, ciphertext: str) -> str:"""ECB decrypt from base64 formatArgs:ciphertext (str): need decrypt dataReturns:str: decrypted content"""ciphertext_bytes = self.base64_to_bytes(ciphertext)content = self.ECB_decrypt_from_bytes(ciphertext_bytes)return content.decode()def ECB_decrypt_from_hex(self, ciphertext: str) -> str:"""ECB decrypt from hex str formatArgs:ciphertext (str): need decrypt dataReturns:str: decrypted content"""content = self.ECB_decrypt_from_bytes(bytes.fromhex(ciphertext))return content.decode()# CBC encryptdef CBC_encrypt_to_bytes(self, content: str, iv: str) -> bytes:"""CBC encrypt to bytes typeArgs:content (str): need encrypt content, must 16x lengthiv (str): iv, need 16X lenReturns:bytes: encrypted data"""        cryptor = AES.new(self.key, AES.MODE_CBC, iv=iv.encode())padding_value = self._get_padding_value(content)ciphertext = cryptor.encrypt(padding_value)return ciphertextdef CBC_encrypt_to_base64(self, content: str, iv: str) -> str:"""CBC encrypt to base64 formatArgs:content (str): need encrypt content, must 16x lengthiv (str): iv, need 16X lenReturns:str: encrypted data with base64 format"""ciphertext = self.CBC_encrypt_to_bytes(content, iv)return self.bytes_to_base64(ciphertext)def CBC_encrypt_to_hex(self, content: str, iv: str) -> str:"""CBC encrypt to hex str formatArgs:content (str): need encrypt content, must 16x lengthiv (str): iv, need 16X lenReturns:str: encrypted data with hex str format"""ciphertext = self.CBC_encrypt_to_bytes(content, iv)return self.bytes_to_hex(ciphertext)# CBC decryptdef CBC_decrypt_from_bytes(self, ciphertext: bytes, iv: str) -> bytes:"""ECB decrypt from bytes typeArgs:ciphertext (bytes): need decrypt dataiv (str): iv, need 16X lenReturns:bytes: decrypted content with bytes type"""cryptor = AES.new(self.key, AES.MODE_CBC, iv=iv.encode())content = cryptor.decrypt(ciphertext)unpadding_value = self._get_unpadding_value(content)return unpadding_valuedef CBC_decrypt_from_base64(self, ciphertext: str, iv: str) -> str:"""ECB decrypt from base64 formatArgs:ciphertext (str): need decrypt dataiv (str): iv, need 16X lenReturns:str: decrypted content"""ciphertext_bytes = self.base64_to_bytes(ciphertext)content = self.CBC_decrypt_from_bytes(ciphertext_bytes, iv)return content.decode()def CBC_decrypt_from_hex(self, ciphertext: str, iv: str) -> str:"""ECB decrypt from hex str formatArgs:ciphertext (str): need decrypt dataiv (str): iv, need 16X lenReturns:str: decrypted content"""content = self.CBC_decrypt_from_bytes(bytes.fromhex(ciphertext), iv)return content.decode()if __name__ == "__main__":# AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demoprint("----------- AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo")key = "12532802"  # 加密keycontent = "405EE11002F3"  # 原文encrypt_res = "c1ee1f3f2d74e02706be9af78aa79ba4".upper()print("content:", content, "key:", key, "exepct:", encrypt_res)AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content))print("decrypt content", AES_Cryptor.ECB_decrypt_from_hex(encrypt_res))# AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demoprint("")print("----------- AES/ECB/pkcs5 | sha1prng key | hex format encrypt result demo")key = "max.bai"  # 加密keycontent = "csdn博客"  # 原文encrypt_res = "97A1B39A480291AD5D38F603C169C644".upper()print("content:", content, "key:", key, "exepct:", encrypt_res)AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content))print("decrypt content", AES_Cryptor.ECB_decrypt_from_hex(encrypt_res))# AES/ECB/nopkcs | no sha1prng key | hex format demoprint("")   print("----------- AES/ECB/nopkcs | no sha1prng key | hex format demo")# 这个demo 有点绕,不看也行key = "43C8B53E236C4756B8FF24E5AA08A549"  # 加密keycontent = "0513011E0005016400000000000000000001000000000000000000000000000000770013011E0005026400000000000000000001000000000000000000000000000000770013011E0005036400000000000000000001000000000000000000000000000000770013011E0005046400000000000000000001000000000000000000000000000000770013011E000505640000000000000000000100000000000000000000000000000077000000000000"  # 原文# 我简单解释下,就是,加密的内容是已经转为16进制了, key也是转为16进制了,所以加密前和解密后都进行了相应的处理encrypt_res = "AB4F4686218A5FF9F07E5248E6B5525D140602A0FAA21176C9A158A010B1A7C0258E80667BF7DD3B6FF57707B373BF75F57AE634D9F1384002AA6B788F4C658DD77572C207AAE3134F91FB690A4F024EF428DE3E1C5F84D0EA9D01B8AB4ED9FE97D7C0D65D447D92F0E306573F30E1360B3DE999E952BAAB9B22E48B8C7B23DC5480027DEE44988F0E86F7A475EEF599C1D7D3331457E582558BC3447E644913ABD63FC221C2E0D49BD712879261FF5F"  # 加密结果print("content:", content, "key:", key, "exepct:", encrypt_res)AES_Cryptor = AES_Crypt(bytes.fromhex(key))content_from_hex = str(bytes.fromhex(content), encoding="utf-8")print("encrypt res", AES_Cryptor.ECB_encrypt_to_hex(content_from_hex))de_res = AES_Cryptor.ECB_decrypt_from_hex(encrypt_res)de_content_from_bytes_to_hex_str = bytes.fromhex(content).hex()print("decrypt content", de_content_from_bytes_to_hex_str)# AES/CBC/nopadding | sha1prng key | hex format encrypt result demoprint("")print("----------- AES/CBC/nopadding | sha1prng key | hex format encrypt result demo")key = "max.bai"  # 加密key, 如果非sha1prng,必须16倍数content = "csdn博客文章csdn博客文章"  # 原文 必须16倍数iv = '1234567812345678'  # 必须16位encrypt_res = "D7DE3D8BBF560BE941EAAE9229879BD20A5ED24976ECCE96187EDC36D0EA0C56".upper()print("content:", content, "key:", key, "exepct:", encrypt_res)AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.NO_PADDING)print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))# AES/CBC/pkcs5 | sha1prng key | hex format encrypt result demoprint("")print("----------- AES/CBC/pkcs5 | sha1prng key | hex format encrypt result demo")key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数content = "csdn博客文章csdn博客文章"  # 原文 如果nopadding必须16倍数iv = '1234567812345678'  # 必须16位encrypt_res = "D7DE3D8BBF560BE941EAAE9229879BD20A5ED24976ECCE96187EDC36D0EA0C564BB4F1208BCDC202969709A5CC4543C7".upper()print("content:", content, "key:", key, "exepct:", encrypt_res)AES_Cryptor = AES_Crypt(AES_Crypt.get_sha1prng_key(key), padding=AES_Crypt.PADDING_PKCS5)print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))# AES/CBC/pkcs5 | no sha1prng key | hex format encrypt result demoprint("")print("----------- AES/CBC/pkcs5 | no sha1prng key | hex format encrypt result demo")key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数content = "csdn博客文章csdn博客文章"  # 原文 必须16倍数iv = '1234567812345678'  # 必须16位encrypt_res = "1a9821e44e483f0a5c39cea0b7d5bd2a47e1b5dc00fd29cf4ddedf08e7931f567cec0d35f5d960967c7f7c066c09263d".upper()print("content:", content, "key:", key, "exepct:", encrypt_res)# key 不够16倍数,padding zeroAES_Cryptor = AES_Crypt(AES_Crypt.padding_zero(key), padding=AES_Crypt.PADDING_PKCS5)print("encrypt res", AES_Cryptor.CBC_encrypt_to_hex(content, iv=iv))print("decrypt content", AES_Cryptor.CBC_decrypt_from_hex(encrypt_res, iv=iv))# AES/CBC/pkcs5 | no sha1prng key | bas64 format encrypt result demoprint("")print("----------- AES/CBC/pkcs5 | no sha1prng key | bas64 format encrypt result demo")key = "max.bai"  # 加密key 如果非sha1prng,必须16倍数content = "csdn博客文章"  # 原文  如果nopadding必须16倍数iv = '1234567812345678'  # 必须16位encrypt_res = "Gpgh5E5IPwpcOc6gt9W9KimbhGPwnBRpSeA6kcZGN/g="print("content:", content, "key:", key, "exepct:", encrypt_res)# key 不够16倍数,padding zeroAES_Cryptor = AES_Crypt(AES_Crypt.padding_zero(key), padding=AES_Crypt.PADDING_PKCS5)print("encrypt res", AES_Cryptor.CBC_encrypt_to_base64(content, iv=iv))print("decrypt content", AES_Cryptor.CBC_decrypt_from_base64(encrypt_res, iv=iv))

Python - AES SHA1PRNG 加密解密总结相关推荐

  1. openssl算法 —— 利用openssl进行BASE64编码解码、md5/sha1摘要、AES/DES3加密解密

    openssl 加密字符串的方法: 一.利用openssl命令进行BASE64编码解码(base64 encode/decode): 1. BASE64编码命令 对字符串'abc'进行base64编码 ...

  2. python下RSA加密解密以及跨平台问题

    项目合作需要,和其他网站通信,消息内容采用RSA加密方式传递.之前没有接触过RSA,于是两个问题出现了: 声明: 环境WIN 7 + python 2.6.6 RSA格式:PEM 一.Python下R ...

  3. AES在线加密解密-附AES128,192,256,CBC,CFB,ECB,OFB,PCBC各种加密

    一.AES在线加密解密:AES 128/192/256位CBC/CFB/ECB/OFB/PCBC在线加密解密|在线工具|在线助手|在线生成|在线制作 http://www.it399.com/aes ...

  4. 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)

    在最近的项目中,前端后台数据交互需要进行加密之后传输使用,以保证系统数据的安全.有关数据加密解密的问题,有很多种加密的方式,在这里我选择了AES的加密方式.特此写下此篇博文,总结讲述下PHP和JS进行 ...

  5. Java AES 256加密解密示例

    Java支持许多安全的加密算法,但是其中一些功能较弱,无法在安全性要求很高的应用程序中使用.例如,数据加密标准(DES)加密算法被认为是高度不安全的.今天介绍一下AES 256加密解密. 什么是 AE ...

  6. [opencv 从零开始 5 ] python 将图片加密解密,图片加隐藏水印,提取水印。

    目录 python 将图片加密解密 原理 代码 效果 python 给图片添加隐藏水印 原理: 代码: 效果: python 将图片加密解密 原理 O代表原始图像,key代表密钥图像,c代表加密后图像 ...

  7. aes js加密php解密实例,基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码...

    [实例简介] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码 [实例截图] [核心代码] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_ ...

  8. python AES对称加密文件、解密文件

    咱也不是学计算机的,咱也不是学网络安全的,咱更不是学密码学的,所以东拼西凑一堆代码,能用就行. 该加解密的秘钥是自己输入的密码加电脑固定序列号,包括网卡MAC地址.CPU序列号.硬盘序列号.主板序列号 ...

  9. Android AES 文件加密解密

    几番折磨终有结果,现将Demo整理出来... [java] view plain copy   package com.king.zjc; import java.io.File; import ja ...

最新文章

  1. 主DNS服务-正向解析
  2. java设计模式---调停者模式
  3. php 子类名,php的继承方法获取子类名
  4. 同事间竞争,你该如何对待?
  5. Mysql:Mysql数据库系统表之详细了解INNODB_TRX、INNODB_LOCKs、INNODB_LOCK_waits、PROCESSLIST表
  6. 数据库---主键约束
  7. [零基础学JAVA]Java SE应用部分-34.Java常用API类库
  8. MySQL访问行更新慢、用户线程大量堆积竟是因为它
  9. 从0开始学习自动化测试框架cypress(五)案例
  10. js this指向分析
  11. 卷积与反卷积、步长(stride)与重叠(overlap)及 output 的大小
  12. 解决Ubuntu系统找不到进程,但是GPU显存占满问题
  13. 已经被删除的PDF怎么用EasyRecovery恢复
  14. 计算机在材料科学中的应用论文,计算机在材料科学中的应用论文.pdf
  15. 从哪查找当前程序所有可用的环境变量?
  16. 【解决】linux磁盘扩容大全:新增磁盘、原磁盘扩容、home分区root分区扩容
  17. 用 python , opencv 打开网络摄像头读取图像
  18. Qt之界面实现技巧——包括任务栏不显示,自定义窗体,最大化最小化按钮等等全面总结
  19. 计算机卡怎么解决,电脑卡怎么办,详细教您电脑卡怎么解决
  20. IM SDK websocket chart room

热门文章

  1. 计算机组成(超详细)+附带思维导图
  2. 在fragment中简单应用百度地图定位
  3. ECShop-v3.0.0漏洞复现
  4. 怎么在自己电脑上搭建一个服务器,以便于外网访问呢?
  5. HDU_2112 HDU Today—最短路(Dijkstra)
  6. 手把手系列:教你安装和设置抓包工具Charles(亲测适用Win10)
  7. 【原创】用VMware 8安装Ubuntu 12.04详细过程(图解)
  8. 《王道论坛计算机考研机试指南》第二章【经典入门】
  9. 怀旧服服务器荣誉系统是啥,怀旧服荣誉系统:荣誉值有哪些获取方式?军衔分数是如何计算的?...
  10. 内网穿透工具天联使用介绍