【问题标题】:Convert AES-128-CBC PHP to JAVA将 AES-128-CBC PHP 转换为 JAVA
【发布时间】:2021-09-13 06:52:06
【问题描述】:

我有使用 PHP 加密/解密的程序,想用 JAVA 编程替换它。

我尝试过转换,但不知何故结果不一样。一直在谷歌和这个论坛搜索这个问题,但结果不匹配。

这是 PHP 代码:

    protected function aes_encode($plain_text) {
    $secret_key = 'TWOFC_ODSACCOUNT';
    $ivBytes = chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0);
    return base64_encode(openssl_encrypt($plain_text, "AES-128-CBC", $secret_key, true, $ivBytes));
}

$plain_text: {"test":"aaaaa"}
Output : /BjE8Fmwcok7rBtD1pdYOO2YkHic7nqXAQQ1/SAsFF8=

这里是 JAVA 代码:

private static final String ALGORITHM = "AES";
private static final byte[] SALT = "TWOFC_ODSACCOUNT".getBytes();

static String getEncrypted(String plainText) {
    if (plainText == null) {
        return null;
    }

    Key salt = getSalt();

    try {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, salt);
        byte[] encodedValue = cipher.doFinal(plainText.getBytes());
        return Base64.getEncoder().encodeToString(encodedValue);
    } catch (Exception e) {
        e.printStackTrace();
    }
    throw new IllegalArgumentException("Failed to encrypt data");
}

static Key getSalt() {
    return new SecretKeySpec(SALT, ALGORITHM);
}

 Output : /BjE8Fmwcok7rBtD1pdYOL6iFK9jqAYS86tEAbA/+io=


  

【问题讨论】:

  • 首先在java中对于AES-128-CBC你需要使用AES/CBC/PKCS5PADDING算法。其次,在cipher.init(Cipher.ENCRYPT_MODE, salt); 中,您需要将 IV 作为第三个参数传递
  • 谢谢回复,代码如下,结果不正确。静态最终字符串 initVector = "0000000000000000"; IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(SALT, "AES");密码密码 = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec,iv); byte[] encodedValue = cipher.doFinal(plainText.getBytes());返回 Base64.getEncoder().encodeToString(encodedValue);输出:Ui8Bdg3SpR6RPcJTY/VkxXOgo65YkeV27kYlc9ctIJ4=
  • 您必须使用IvParameterSpec iv = new IvParameterSpec(new byte[16]);。请注意,像零 IV 这样的静态 IV 是不安全的。在 PHP 代码中,OPENSSL_RAW_DATA 应该用作第 4 个参数,而不是 true

标签: java php encryption


【解决方案1】:

如您所见,密文开头相同。这通常意味着最终块的填充有问题,或者模式不正确,或两者兼而有之。

目前您正在使用"AES" 作为算法。这通常默认为"AES/ECB/PKCS5Padding"。您需要"AES/CBC/PKCS5Padding" 来进行正常的 CBC 操作。您应该提供一个全零的 IV 以符合 PHP 代码。

可能是 PHP / openssl_encrypt 中的 true 参数导致 ZERO_PADDING 被触发调用。在这种情况下,您应该手动创建一个零填充。这意味着将零添加到明文或最后(部分)明文块,直到明文字节数是块大小的倍数。您还应该在解密后删除零字节。在这种情况下,您当然会改用"AES/CBC/NoPadding"

【讨论】:

    猜你喜欢
    • 2021-03-21
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 2013-08-11
    • 1970-01-01
    • 2015-07-21
    • 2019-08-17
    相关资源
    最近更新 更多