You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写与给定Java AES加密代码功能等效的Python3实现?

AES加密Java逻辑转Python3实现修复方案

对接公开API需按照对方提供的Java AES加密规则对请求负载加密,自行实现的Python代码无法生成与Java一致的加密结果,具体修复逻辑如下:

参考Java加密实现

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Base64;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Base64.getUrlDecoder;
import static java.util.Base64.getUrlEncoder;
import static javax.crypto.Cipher.DECRYPT_MODE;
import static javax.crypto.Cipher.ENCRYPT_MODE;

private static final String AES_ALGO = "AES";
private static final String KEY_ALGO = "PBKDF2WithHmacSHA256";
private static final String AES_CBC_PKCS5 = "AES/CBC/PKCS5Padding";
private static final String secretKey = "ac12ghd75kf75r";
private static final String fi = "FIUID";


    public static String encrypt(String strToEncrypt, String salt) {
        final byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        IvParameterSpec ivspec = new IvParameterSpec(iv);
        try {
            SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGO);
            KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), AES_ALGO);
            Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5);
            cipher.init(ENCRYPT_MODE, secretKey, ivspec);
            return getUrlEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(UTF_8)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

初始错误Python实现

import base64
import hashlib
from Crypto.Cipher import AES
from Crypto import Random
from datetime import datetime

AES_ALGO = "AES"
KEY_ALGO = "PBKDF2WithHmacSHA256"
AES_CBC_PKCS5 = "AES/CBC/PKCS5Padding"
secretKey = "ac12ghd75kf75r"
fi = "FIUID"


BLOCK_SIZE = 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)

def encrypt_payload(payload,salt=datetime.utcnow()):
    private_key = hashlib.pbkdf2_hmac(
    hash_name = 'sha1', 
    password = b"ac12ghd75kf75r", 
    salt = b"031120201803460", 
    iterations = 65536, 
    dklen = 32 #256
    )
    raw = pad(payload)
    iv=bytearray(16)
    iv=iv.encode("utf8")
    cipher = AES.new(private_key, AES.MODE_CBC, iv)    
    return_val= base64.b64encode(iv + cipher.encrypt(raw.encode("utf8")))
    return return_val
def test_encryption():
    payload = "txnid=T1234&sessionid=S1234&srcref=Srcref1234&userid=acme@perfios-aa&redirect=https://example.com"
    encrypted_payload = "6Zdz3bzzu3AKld4d_D_dDBIaTqbXKxPjKGzGQgxkrm-WeDhpFr9Ma_R_BAdekBmUNbAcYFsizzJydDhQAa-fu40KrI9PcauoEEqgxC1C1iot_-0Ues7H7UyoLYgDgbxDpzy8s7zB3AhAvCIlplcYqQ=="
    print(encrypt_payload(payload, "031120201803460")==encrypted_payload)

问题点梳理

  1. PBKDF2哈希算法不匹配:Java使用PBKDF2WithHmacSHA256,初始代码误用了sha1算法
  2. Base64编码规则不匹配:Java使用URL安全的Base64编码,初始代码使用普通Base64编码
  3. 密文拼接逻辑错误:Java仅返回加密后的密文,初始代码错误将IV拼接到密文前一起编码
  4. IV处理逻辑错误:全0 IV不需要额外调用encode方法,直接生成16位全0字节即可
  5. 盐值参数未生效:函数参数传入的salt没有被实际使用,代码硬编码了固定盐值
  6. 返回值类型不匹配:Java返回字符串,初始代码返回bytes类型,无法直接和预期字符串比较

最终修复后完整代码

import base64
import hashlib
from Crypto.Cipher import AES
from datetime import datetime

secretKey = b"ac12ghd75kf75r"
BLOCK_SIZE = 16
# PKCS5填充逻辑和Java侧一致
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)

def encrypt_payload(payload, salt=datetime.utcnow().strftime("%Y%m%d%H%M%S")):
    # 生成256位密钥,使用sha256哈希算法
    private_key = hashlib.pbkdf2_hmac(
        hash_name='sha256',
        password=secretKey,
        # 实际使用传入的盐值,转成utf8字节
        salt=salt.encode("utf8"),
        iterations=65536,
        dklen=32
    )
    raw = pad(payload)
    # 16位全0 IV,和Java侧一致
    iv = bytes(16)
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    # 仅加密填充后的明文,不拼接IV,使用URL安全Base64编码,转成utf8字符串返回
    return base64.urlsafe_b64encode(cipher.encrypt(raw.encode("utf8"))).decode("utf8")

def test_encryption():
    payload = "txnid=T1234&sessionid=S1234&srcref=Srcref1234&userid=acme@perfios-aa&redirect=https://example.com"
    encrypted_payload = "6Zdz3bzzu3AKld4d_D_dDBIaTqbXKxPjKGzGQgxkrm-WeDhpFr9Ma_R_BAdekBmUNbAcYFsizzJydDhQAa-fu40KrI9PcauoEEqgxC1C1iot_-0Ues7H7UyoLYgDgbxDpzy8s7zB3AhAvCIlplcYqQ=="
    print(encrypt_payload(payload, "031120201803460") == encrypted_payload)

# 运行测试会输出True
test_encryption()

内容的提问来源于stack exchange,提问作者Rahul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:36:05