[python3] 用pycryptodome实现AES算法加密中文

写在前面

如有问题可在评论区留言,我看到后第一时间回复的

一、背景

将java代码的AES加密demo用python语言实现(通过pycryptodome包)

二、关键词

Python3、pycryptodome、AES/CBC/PKCS5padding、中文

三、java代码加密demo

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.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 = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] raw = sKey.getBytes();  // 密钥转成byte
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量转成byte
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(str.getBytes("utf-8"));
        return Base64.encodeBase64String(encrypted); //base64编码
    } catch (Exception ex) {
        return null;
    }
}

四、java代码解密demo

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.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 = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); //偏移量
        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代码解释说明

通过以上java代码可以知晓以下信息:

AES加密相关

  1. AES加密模式:CBC
  2. 填充方式:PKCS5
  3. 偏移量:密钥截取前16位
  4. 输出:base64
  5. 字符:utf-8

其他信息

  1. 密钥是string类型,使用时需转成bytes
  2. 偏移量也是string类型,使用时需转成bytes

六、python代码实现

使用 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,所以需要以len(s.encode()),而不是len(s)计算补码)
pad = lambda s: s + (BLOCK_SIZE - len(s.encode()) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s.encode()) % 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 = AES.new(key=self.key.encode(), mode=AES.MODE_CBC, IV=self.iv.encode())
        encrypted_text = cipher.encrypt(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 = AES.new(key=self.key.encode(), mode=AES.MODE_CBC, IV=self.iv.encode())
        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(算法/模式/补码方式) 加密'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

  • 目录一、对称加密 1、对称加密是什么 2、对称加密的优点 3、对称加密的问题 4、对称加密的应用场景 5、对称加密...
    意一ineyee阅读 62,527评论 8 110
  • 1. ASCII 编码 ASCII(American Standard Code for Information ...
    s酸菜阅读 8,834评论 0 8
  • 背景:工作需要,部分数据进行了加密传输,对方使用了AES对密码进行了加密,需要获取到解密的数据。目标:通过密钥成功...
    Ziger丶阅读 78,915评论 4 64
  • 此刻,妈妈的脸让她害怕。 她看见面前的妈妈眼里快要喷出火来,脸孔因为嘶吼而变得狰狞。她不由得自动过滤掉妈妈抛过来的...
    多瑞果阅读 223评论 0 1
  • 反省三组学员【日精进打卡第105天】 【知~学习】 诵读《六项精进》大纲1遍 诵读《大学》1遍 阅读《活法》篇 阅...
    周冲_22e8阅读 193评论 0 0

友情链接更多精彩内容