⽤python3实现AESCBCPKCS5padding算法加解密将java代码的AES加密demo⽤python语⾔实现(通过pycryptodome包)
Python3、pycryptodome、AES/CBC/PKCS5padding、中⽂
pto.Cipher;
pto.spec.IvParameterSpec;
pto.spec.SecretKeySpec;
import dec.binary.Base64;
private static String sKey = "********************************"; //密钥是string类型
private static String ivParameter = sKey.substring(0, 16); ; //偏移量是密钥截取16位,也是string类型
/**
* AES 加密
* @param str 明⽂
* @param key 秘钥
* @return 返回加密密⽂
* @throws Exception
*/
public static String encrypt(String str) throws Exception {
try {
Cipher cipher = Instance("AES/CBC/PKCS5Padding");
byte[] raw = Bytes(); // 密钥转成byte
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new Bytes()); //偏移量转成byte
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.Bytes("utf-8"));
deBase64String(encrypted); //base64编码
} catch (Exception ex) {
return null;
}
}
pto.Cipher;
pto.spec.IvParameterSpec;
pto.spec.SecretKeySpec;
import dec.binary.Base64;
private static String sKey = "********************************";
private static String ivParameter = sKey.substring(0, 16); ;
/**
* AES 解密
* @param str 密⽂
* @param key 秘钥
* @return 返回明⽂
* @throws Exception
*/
public static String decrypt(String str) throws Exception {
try {
byte[] raw = Bytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Instance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new Bytes()); //偏移量
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] encrypted1 = Base64.decodeBase64(str);
byte[] original = cipher.doFinal(encrypted1);
String originalString = new String(original, "utf-8");
return originalString;
} catch (Exception ex) {
return null;
}
}
通过以上java代码可以知晓以下信息:
AES加密相关:
AES加密模式:CBC
填充⽅式:PKCS5
偏移量:密钥截取前16位python转java代码
输出:base64
字符:utf-8
其他信息:
密钥是string类型,使⽤时需转成bytes
偏移量也是string类型,使⽤时需转成bytes
使⽤ pycryptodome 进⾏ AES/CBC/PKCS5(算法/模式/补码⽅式) 加密
from Crypto.Cipher import AES
from base64 import b64decode, b64encode
BLOCK_SIZE = AES.block_size
# 不⾜BLOCK_SIZE的补位(s可能是含中⽂,⽽中⽂字符utf-8编码占3个位置,gbk是2,所以需要以de()),⽽不是len(s)计算补码)
pad = lambda s: s + (BLOCK_SIZE - de()) % BLOCK_SIZE) * chr(BLOCK_SIZE - de()) % BLOCK_SIZE)
# 去除补位
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
class AESCipher:
def __init__(self, secretkey: str):
self.key = secretkey # 密钥
self.iv = secretkey[0:16] # 偏移量
def encrypt(self, text):
"""
加密:先补位,再AES加密,后base64编码
:param text: 需加密的明⽂
:return:
"""
# text = pad(text) 包pycrypto的写法,加密函数可以接受str也可以接受bytess
text = pad(text).encode() # 包pycryptodome 的加密函数不接受str
cipher = w(key=de(), mode=AES.MODE_CBC, IV=de())
encrypted_text = pt(text)
# 进⾏64位的编码,返回得到加密后的bytes,decode成字符串
return b64encode(encrypted_text).decode('utf-8')
def decrypt(self, encrypted_text):
"""
解密:偏移量为key[0:16];先base64解,再AES解密,后取消补位
:param encrypted_text : 已经加密的密⽂
:return:
"""
encrypted_text = b64decode(encrypted_text)
cipher = w(key=de(), mode=AES.MODE_CBC, IV=de())
decrypted_text = cipher.decrypt(encrypted_text)
return unpad(decrypted_text).decode('utf-8')
密钥应由16位,24位,32位字母或数字组成,。本例使⽤32位的密钥进⾏加密
###secretkey = '6agrioBE1D9yoGOX4yyDMyMFs72jYvJ8' # 密钥
text = '使⽤ pycryptodome 进⾏ AES/CBC/PKCS5(算法/模式/补码⽅式) 加密' # 待加密的明⽂
encrypted_text = AESCipher(secretkey).encrypt(text) # 加密
>>>'yzPmbAOq5Wl8bMYcG/UWgY46r5xjq5VYFbJVqXWnpZQofmk0OXpkato7dT0diuV9qRsG+dQ209wfVt1NaSopt9syqAXm6zH0I91TaLD4Ua4=' decrypted_text = AESCipher(secretkey).decrypt(encrypted_text) # 解密
>>>'使⽤ pycryptodome 进⾏ AES/CBC/PKCS5(算法/模式/补码⽅式) 加密'
from Crypto.Util.Padding import pad
import base64
import random
from base64 import b64decode, b64encode
from Crypto.Cipher import AES
# 去除补位
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
def aes_encrypt(key, aes_str):
# 使⽤key,选择加密⽅式
vi = "16-Bytes--String"
aes = de('utf-8'), AES.MODE_de('utf8'))
pad_pkcs7 = pad(de('utf-8'), AES.block_size, style='pkcs7') # 选择pkcs7补全
encrypt_aes = pt(pad_pkcs7)
# 加密结果
encrypted_text = debytes(encrypt_aes), encoding='utf-8') # 解码
encrypted_text_str = place("\n", "")
# 此处我的输出结果⽼有换⾏符,所以⽤了临时⽅法将它剔除
return encrypted_text_str
def aes_decrypt(key,text):
"""
解密:偏移量为key[0:16];先base64解,再AES解密,后取消补位
:param encrypted_text : 已经加密的密⽂
:return:
"""
iv = "16-Bytes--String"
encrypted_text = b64decode(text)
cipher = w(de(), mode=AES.MODE_CBC, de())
decrypted_text = cipher.decrypt(encrypted_text)
return unpad(decrypted_text).decode('utf-8')
if __name__ == '__main__':
# key的长度需要补长(16倍数),补全⽅式根据情况⽽定,此处我就⼿动以‘0’的⽅式补全的32位key
# key字符长度决定加密结果,长度16:加密结果AES(128),长度32:结果就是AES(256)
# key = "".join(random.sample("0123efghjkl456mnopqstuvwsz789abcdef", 16))
key = "4F5U384JGMK35XUV"
# 加密字符串长同样需要16倍数:需注意,不过代码中pad()⽅法⾥,帮助实现了补全(补全⽅式就是pkcs7)
aes_str = '{"appKey":"F34AA6648478A344","channel":"17","data":{"phone":"199********"},"imeiIdfa":"355455060276059","oaid":"","os":" Android","uuid":"ffffffff-fd9f-ae04-fb56-4c4c00000000","version":"42"}'
encryption_result = aes_encrypt(key, aes_str)
print(encryption_result)
# text = "aNUkeNljo4XhsxBX5G92JL6M/DMm+KG9fUq1X80s9d2zDSO2IBvYrm8kce8SlFAXdhqsMLVjTSpiyZatS2wP+haxLha/aF6PabApn9fFYKb RjA++d6ZkWDjPfU62ik1eWBnQaUYt4mwZUEJjnknXCrVGVjtg0mrDQzwoQzAFzKK9Wy4c5riA84WColA1+dRj+tbbxIuuXP7IXxp/246Bg61a4plA3nBu SNrZ/SorjSavBAcK25Z2KMZ2q9ni1q//"
text = "XElQzQ8wkCFRt9QXe178vUDUTRLC2QpSdOPxTnutN4c="
decrypt_result = aes_decrypt(key, text)
print(decrypt_result)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论