2017-07-31 86 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。


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