【问题标题】:How to decrypt data in Java that was encrypted by PHP method openssl_encryp aes-256-cbc?如何解密通过 PHP 方法 openssl_encryp aes-256-cbc 加密的 Java 数据?
【发布时间】:2017-08-01 06:45:19
【问题描述】:
public static void main(String[] args) throws Exception {
    String iv = "0102030405060708";
    String key = "1882051051AgVfZUKJLInUbWvOPsAP6LM6nBwLn14140722186";

    byte[] aaa = AES_cbc_decrypt("hv208Otx0FZL32GUuErHDLlZzC3zVEGRt56f8lviQpk=", key, iv);
    System.out.println(new String(aaa));
}

private static final String ALGORITHM = "AES/CBC/PKCS5Padding";

public static byte[] AES_cbc_decrypt(String content,String key,String iv) throws Exception 
{
    byte[] contentBytes = Base64.decode(content);
    byte[] keyBytes = key.substring(0, 16).getBytes();
    byte[] ivBytes = iv.getBytes();

    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));
    byte[] decbbdt = cipher.doFinal(contentBytes);
    return decbbdt;
}

使用此代码运行,我得到以下异常:

线程“主”javax.crypto.BadPaddingException 中的异常:给定最终块未正确填充

可以通过php方法解密

openssl_decrypt(base64_decode($encryptData), 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);

【问题讨论】:

  • 为什么要将密钥从 50 字节减少到 16 字节? AFAIK 在 php 中它被表示为密码而不是密钥,这意味着它可以是任意长度,并且使用密钥推导函数来生成真正的密钥。
  • 你需要展示你完整的php代码。目前尚不清楚 key 和 IV 是如何实际解码的。
  • 永远不要在没有参数的情况下使用String#getBytes,因为默认字符集可能会在不同系统之间发生变化。

标签: java encryption aes


【解决方案1】:

您尝试使用 16 字节或 128 位的密钥进行解密。但是,您一直在使用 AES-256,其中 256 表示密钥大小:当然是 32 字节。

现在 C 和 C 库(例如 OpenSSL)通常使用指针算法来确定字节数。在指定密钥时,它们通常采用指针地址和字节数(或者对于较低级别的库,32 位字等)

因此,当指定大于 32 个字符/字节的键时,该键很可能会减少到 32 个字节(或 C 中的 chars,其中字节和字符永远混淆)。但是,在您的 Java 代码中,您将密钥减少到 16 个字节。这将导致在 C 中使用 AES-256,在 Java 中使用 AES-128。


故事的寓意:不要混淆密码/字符串和密钥。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 2013-08-11
    • 2014-02-06
    • 2019-01-30
    • 2020-01-14
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多