2017-07-31 81 views
3
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; 
} 

与此代码运行,我得到了如下异常:线程“main” javax.crypto.BadPaddingException如何解密通过PHP方法加密的Java数据openssl_encryp aes-256-cbc?

例外:由于最后一个块未正确填充

它可以解密通过php方法

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

为什么要将密钥从50个字节减少到16个? AFAIK在PHP中被称为密码不是密钥,这意味着它可以是任意长度的,并且密钥派生函数用于生成真实密钥。 – Robert

+0

您需要显示完整的PHP代码。目前还不清楚密钥和IV是如何被实际解码的。 –

+0

切勿使用不带参数的'String#getBytes',因为默认字符集可能在不同系统之间发生变化。 –

回答

0

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

现在,C和C库(如OpenSSL)通常使用指针算术来确定字节数。当指定密钥时,他们通常会获取一个指针地址和一定数量的字节(或用于较低级别的库,32位字等)。

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


道德故事:不要混淆密码/字符串和键。