> 技术文档 > 【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现


PBEWithMD5AndDES明文加密解密算法

  • 前言
  • 一、JAVA中使用PBEWithMD5AndDES算法
  • 二、PBEWithMD5AndDES算法分析
    • 1. 加密过程
      • 数据流程
      • 各算法介绍
    • 2. 解密过程
      • 数据流程
      • 各算法介绍
  • 三、Python中PBEWithMD5AndDES算法实现
    • 1. Python加密代码
    • 2. Python解密代码
  • 总结

前言

各项目、平台的功能往往涉及到数据库存储、读取等操作,连接数据库时需要用户名、密码等敏感信息。出于信息保护的角度,需要对这些敏感信息进行加密。

在JAVA中,通常使用加密算法PBEWithMD5AndDES,使用方式简单:实例化对象、设置固定口令,即可生成加密密文。

目前不少功能、算法开发均基于python编程,在python、JAVA联合开发的项目中,需要保证加密解密方式一致。然而,python并未直接提供调用包,因此本文对PBEWithMD5AndDES算法原理进行分析,在python中实现同样操作,保证两种编程环境下的结果统一。


一、JAVA中使用PBEWithMD5AndDES算法

在JAVA中调用PBEWithMD5AndDES算法的方式如下:

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;import org.jasypt.encryption.pbe.config.EnvironmentPBEConfig;// 加密public void get_Encrypt() { // 实例化 StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); // 配置加密算法和固定口令 EnvironmentPBEConfig config = new EnvironmentPBEConfig(); config.setAlgorithm(\"PBEWithMD5AndDES\"); // 设置成PBEWithMD5AndDES算法  config.setPassword(\"forTest\"); // 用于加密的口令,解密时也需要 encryptor.setConfig(config); String myPwd = \"123456test\"; // 需要加密的明文密码 String encryptedPwd = encryptor.encrypt(myPwd); // 加密 System.out.println(\"加密结果为:\" + encryptedPwd);}// 解密public static void testPwdDecrypt() { // 实例化 StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor(); // 配置加密算法和固定口令 EnvironmentPBEConfig config = new EnvironmentPBEConfig(); config.setAlgorithm(\"PBEWithMD5AndDES\"); // 设置成PBEWithMD5AndDES算法 config.setPassword(\"forTest\"); // 用于加密的口令,同加密 String encryptedPwd = \"EVjR4mo1JvBbhzIMVEuPMlgVJn43PB1R\"; // 需要解密的加密密码 String myPwd = encryptor.decrypt(encryptedPwd); // 解密 System.out.println(\"解密结果为:\" + myPwd);}

调用上述功能的执行结果为:

加密结果为:EVjR4mo1JvBbhzIMVEuPMlgVJn43PB1R解密结果为:123456test

二、PBEWithMD5AndDES算法分析

1. 加密过程

数据流程

PBEWithMD5AndDES算法的加密过程整体流程如下:使用PBKDF1算法得到密钥和初始化向量、通过DES加密算法对明文密码进行加密、得到的加密信息联合盐一起进行Base64编码,最终输出密文。
【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

各算法介绍

(1) PBKDF1算法
输入:口令、系统随机生成的8字节盐、迭代次数(默认为1000次)
输出:16位输出(前8位为密钥,后8位为初始化向量IV)
过程:口令与盐的组合作为输入,使用MD5(哈希)对输入进行加密,按照指定迭代次数进行多次迭代,每一次迭代的输入为上一次MD5的结果。最终输出32位字符串,取中间的第9位到第24位的部分,得到16位长度的结果。

  • MD5的算法原理可参考:MD5算法实现原理

(2) DES加密算法
输入:密钥、初始化向量IV、明文
输出:加密信息
过程:将待加密数据以64bit为单位拆分成若干数据块,然后再进行外层、内层两重迭代。外层迭代为数据块之间的迭代,使用密码分组链接模式(Cipher Block Chaining,CBC)对各数据块进行加密;内层迭代在各数据块的内部,通过Feistel网络实现。

  • CBC模式加密:初始化向量与第一个明文数据块进行异或运算,结果与第二个明文数据块再进行异或,依次往后,得到密文。
    【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现
  • Feistel网络加密:将输入划分为左、右两侧数据,“子密钥”指的是本轮加密所使用的密钥。在Feistel网络中,每一轮都需要使用一个不同的子密钥。轮函数(典型的包括置换、代换、置换与代换的组合)的作用是根据“右侧”和子密钥生成对“左侧”加密的比特序列。每一轮加密左、右需调换一次数据。
    【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

(3) Base64编码
输入:随机生成的8字节盐+加密信息
输出:密文
过程:将原始数据按 3 字节分组(如果数据长度不是 3 的倍数,则用 0 字节填充,在最后用 = 号填补);24位的数据拆分成 4 组,每组 6 位;每 6 位的二进制值被解释为一个整数(0~63),用这个整数查找 Base64 的字符表,对应输出一个字符。Base64字符表如下:
【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

2. 解密过程

数据流程

PBEWithMD5AndDES算法的解密过程就是将加密流程倒着走一遍:对密文进行Base64解码,从解码结果得到加密信息和盐;再利用盐、口令、迭代次数根据PBKDF1算法得到密钥和初始化向量;最后使用DES解密算法得到明文。
【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

各算法介绍

(1) Base64解码
输入:密文
输出:解码结果,前8位为盐,剩余字节为加密的信息
过程:

  1. 识别出 Base64 编码的字符串中的有效字符(即大写字母 A-Z、小写字母 a-z、数字 0-9、“+”和“/”);
  2. 将每个有效字符转换为对应的6位二进制值(例如,“A”对应 000000,“B”对应 000001等);
  3. 将6位二进制值按顺序拼接起来,每8位一组,转换为对应的 ASCII 码值,从而得到原始的二进制数据;
  4. 如果编码字符串末尾有“=”填充字符,则在解码时忽略这些填充字符,并根据填充字符的数量确定需要丢弃的二进制位(如果末尾有一个“=”,则丢弃最后 4 个二进制位;如果末尾有两个“=”,则丢弃最后 8 个二进制位)

(2) PBKDF1算法
流程同加密

(3) DES解密算法
输入:密钥、初始化向量IV、密文
输出:明文
过程:将密文数据以64bit为单位拆分成若干数据块,然后再进行外层、内层两重迭代。外层迭代为数据块之间的迭代,使用密码分组链接模式(Cipher Block Chaining,CBC)对各数据块进行解密;内层迭代在各数据块的内部,通过Feistel网络实现。

  • CBC解密:初始化向量与第一个密文数据块进行异或运算,结果与第二个密文数据块再进行异或,依次往后,得到明文。
    【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

  • Feistel网络加密:将输入划分为左、右两侧数据,“子密钥”指的是本轮加密所使用的密钥。在Feistel网络中,每一轮都需要使用一个不同的子密钥。轮函数(典型的包括置换、代换、置换与代换的组合)的作用是根据“右侧”和子密钥生成对“左侧”加密的比特序列。每一轮加密左、右需调换一次数据。
    【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

三、Python中PBEWithMD5AndDES算法实现

1. Python加密代码

import base64from Crypto.Cipher import DESfrom Crypto.Hash import MD5from Crypto.Protocol.KDF import PBKDF1from Crypto.Util.Padding import padimport osdef encrypt_pbe_with_md5_and_des(password, plaintext): # 生成随机的8字节盐 salt = os.urandom(8) # 使用PBKDF1生成密钥和IV key_iv = PBKDF1(password.encode(\'utf-8\'), salt, 16, 1000, MD5) key = key_iv[:8] iv = key_iv[8:16] # 使用DES加密 cipher = DES.new(key, DES.MODE_CBC, iv=iv) padded_data = pad(plaintext.encode(\'utf-8\'), 8) # PKCS7填充 encrypted_data = cipher.encrypt(padded_data) # 组合盐和加密数据,并进行Base64编码 combined = salt + encrypted_data encrypted_b64 = base64.b64encode(combined).decode(\'utf-8\') return encrypted_b64if __name__ == \"__main__\": # 配置口令和明文 setPassword = \"forTest\" # 口令 myPwd = \"123456test\" # 加密 encrypted_pwd = encrypt_pbe_with_md5_and_des(setPassword, myPwd) print(\"++++++++++++++++++++++++++++++\") print(f\"+ 原密码为:{myPwd}\") print(f\"+ 加密后的密码为:{encrypted_pwd}\") print(\"++++++++++++++++++++++++++++++\")

注意:由于每次执行加密时,会随机生成一个8字节盐,因此每次加密的结果都是不一样的。

2. Python解密代码

import base64from Crypto.Cipher import DESfrom Crypto.Hash import MD5from Crypto.Protocol.KDF import PBKDF1def dencrypt_pbe_with_md5_and_des(password, encrypted_b64): encrypted_data = base64.b64decode(encrypted_b64) salt = encrypted_data[:8] ciphertext = encrypted_data[8:] # 生成密钥和IV key_iv = PBKDF1(password.encode(\'utf-8\'), salt, 16, 1000, MD5) key = key_iv[:8] iv = key_iv[8:16] # 解密 cipher = DES.new(key, DES.MODE_CBC, iv=iv) decrypted = cipher.decrypt(ciphertext) # 去除PKCS7填充 pad_length = decrypted[-1] decrypted = decrypted[:-pad_length] return decrypted.decode(\'utf-8\')if __name__ == \"__main__\": setPassword = \"forTest\" pending_pwd = \"EVjR4mo1JvBbhzIMVEuPMlgVJn43PB1R\" my_pwd = dencrypt_pbe_with_md5_and_des(setPassword, pending_pwd) print(\"++++++++++++++++++++++++++++++\") print(f\"+ 加密密码为:{pending_pwd}\") print(f\"+ 解密后的密码为:{my_pwd}\") print(\"++++++++++++++++++++++++++++++\")

使用JAVA的加密结果进行检验,得到结果为123456test,与加密前的明文一致:
【Python | JAVA】PBEWithMD5AndDES加密、解密算法—JAVA分析及Python实现

总结

本文对JAVA中的PBEWithMD5AndDES加密、解密算法原理进行了分析,在Python中实现了同样的算法逻辑,支持JAVA、Python作为编程语言的项目开发。