2012-05-31 82 views
8

PHP加密功能Java的AES CBC解密

$privateKey = "1234567812345678"; 
$iv = "1234567812345678"; 
$data = "Test string"; 

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $privateKey, $data, MCRYPT_MODE_CBC, $iv); 

echo(base64_encode($encrypted)); 

Result: iz1qFlQJfs6Ycp+gcc2z4w== 

當我嘗試使用下面的函數在Java中來解密這個結果,所有我回來是爲@ÔBKxnfÈ〜¯Ô'M而我期待「測試字符串」。任何想法,我錯了?感謝

public static String decrypt() throws Exception{ 
    try{ 
     String Base64EncodedText = "iz1qFlQJfs6Ycp+gcc2z4w=="; 
     String decodedText = com.sun.xml.internal.messaging.saaj.util.Base64.base64Decode(Base64EncodedText); 
     String key = "1234567812345678"; 
     String iv = "1234567812345678"; 

     javax.crypto.spec.SecretKeySpec keyspec = new javax.crypto.spec.SecretKeySpec(key.getBytes(), "AES"); 
     javax.crypto.spec.IvParameterSpec ivspec = new javax.crypto.spec.IvParameterSpec(iv.getBytes()); 

     javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/NoPadding"); 
     cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keyspec, ivspec); 
     byte[] decrypted = cipher.doFinal(decodedText.getBytes()); 

     String str = new String(decrypted); 

     return str; 

    }catch(Exception e){ 
     return null; 
    } 
} 
+0

可能重複的HTTP ://stackoverflow.com/questions/10842509/php-java-aes-cbc-encryption-different-results) –

回答

15

編輯:從Java 8的Java現在包括一個可接受的Base64類,java.util.Base64


此行

String decodedText = com.sun.xml.internal.messaging.saaj.util.Base64.base64Decode(Base64EncodedText); 

看起來是錯誤的。而應使用apache commons codec類或Harder base64類。另外,mcrypt,zero padding使用的默認填充可能是錯誤的,並且很難在其他語言中使用結果。 mcrypt_encrypt web pages的用戶評論部分提供瞭如何執行此操作的示例。

這裏有一個小例子,它使用apache commons類來解密你的字符串。

import java.nio.charset.Charset; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import org.apache.commons.codec.binary.Base64; 
import org.apache.commons.codec.binary.Hex; 

public class AESToy3 { 

    private static final Charset ASCII = Charset.forName("US-ASCII"); 

    public static void main(String[] args) throws Exception { 
     String base64Cipher = "iz1qFlQJfs6Ycp+gcc2z4w=="; 
     byte [] cipherBytes = Base64.decodeBase64(base64Cipher); 
     byte [] iv = "1234567812345678".getBytes(ASCII); 
     byte [] keyBytes = "1234567812345678".getBytes(ASCII); 

     SecretKey aesKey = new SecretKeySpec(keyBytes, "AES"); 

     Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING"); 
     cipher.init(Cipher.DECRYPT_MODE, aesKey, new IvParameterSpec(iv)); 

     byte[] result = cipher.doFinal(cipherBytes); 
     System.out.println(Hex.encodeHexString(result)); 
    } 

} 

這將產生以下輸出:

5465737420737472696e670000000000 

其中,當譯碼爲ASCII併除去尾隨零給你Test string

[PHP爪哇AES CBC加密不同結果](的
+0

第一次投票,關閉之前:) –

+0

非常感謝GregS。很好解釋。 – user812120

+0

謝謝。但關鍵是與IV不同 - 克隆它們只會讓讀者感到困惑。 –