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

PHP的MCRYPT_RIJNDAEL_256加密转Java实现求助

解决PHP Rijndael-256 CBC加密转Java实现的问题

我来帮你搞定这个对接遗留API的加密问题!你遇到的报错本质是PHP和Java对Rijndael算法的定义差异,以及参数配置没对齐导致的,下面给你拆解原因+完整实现:

首先得明确PHP代码里的几个关键细节,这是踩坑核心:

  • MCRYPT_RIJNDAEL_256 指的是**块大小为256位(32字节)**的Rijndael算法,不是你以为的密钥长度256(刚好你的密钥是32字节=256位,这是巧合)。
  • Java标准库的AES只支持128位块大小,所以直接用javax.crypto会因为IV长度(32字节)不符合16字节要求报错。
  • BouncyCastle支持完整的Rijndael算法(包括256位块大小),你之前用它报错是因为没正确指定块大小参数。

正确实现步骤

1. 先加BouncyCastle依赖

如果用Maven,在pom.xml里添上这个依赖(版本可以用最新稳定版):

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

2. 完整Java代码实现

下面的代码完全对齐PHP的加密逻辑,复制过去就能用:

  • 用Rijndael-256(32字节块大小)
  • CBC模式
  • IV和密钥完全相同(和PHP逻辑一致)
  • 零填充(PHP的mcrypt_encrypt默认填充方式,你的输入是32的倍数,不会额外补零)
  • 最终输出Base64编码结果
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class LegacyApiEncryptor {
    public static void main(String[] args) throws Exception {
        // 替换成你要加密的32倍数长度字符串
        String plainText = "****需加密的字符串,长度为32的倍数********************";
        // 替换成你的32字节密钥
        String secretKey = "32ByteKey-asdcxzasdsadasdasdasda";
        
        byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
        byte[] ivBytes = keyBytes; // IV和密钥完全相同,和PHP保持一致
        byte[] inputBytes = plainText.getBytes(StandardCharsets.UTF_8);

        // 初始化Rijndael引擎,必须指定块大小为256位(32字节)
        BlockCipher rijndaelEngine = new RijndaelEngine(256);
        // 组合CBC模式+零填充
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(rijndaelEngine), new ZeroBytePadding());
        
        // 构建加密参数:密钥+IV
        CipherParameters params = new ParametersWithIV(new KeyParameter(keyBytes), ivBytes);
        cipher.init(true, params); // true表示加密模式

        // 处理加密输出
        byte[] outputBuffer = new byte[cipher.getOutputSize(inputBytes.length)];
        int processedLength = cipher.processBytes(inputBytes, 0, inputBytes.length, outputBuffer, 0);
        // 完成加密,处理最后一块
        processedLength += cipher.doFinal(outputBuffer, processedLength);

        // 转Base64编码,和PHP的base64_encode结果一致
        String encryptedBase64 = Base64.getEncoder().encodeToString(outputBuffer, 0, processedLength);
        System.out.println("加密结果:" + encryptedBase64);
    }
}

几个必须注意的细节

  • 块大小必须指定256:如果忘记在RijndaelEngine构造函数传256,默认会用128位块大小,和PHP的MCRYPT_RIJNDAEL_256完全不匹配,解密肯定失败。
  • 填充方式必须用零填充:PHP的mcrypt_encrypt默认用零填充,千万别用PKCS7/PKCS5填充,否则后端解密会报错。
  • 字符集要对齐:PHP里字符串转字节默认是环境编码,如果你PHP代码里是UTF-8,Java用StandardCharsets.UTF_8就没问题,如果是其他编码(比如GBK),要对应修改。
  • IV长度必须32字节:因为块大小是256位,所以IV必须和块大小一致,这里直接用密钥当IV,完全符合PHP逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:07:43