2012-05-31 10 views
8

PHP Funkcja SzyfrowanieJava AES CBC Rozszyfrowanie

$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== 

Kiedy próbuję odszyfrować ten wynik w Javie przy użyciu funkcji poniżej, wszystko wrócę IS @ ÔBKxnfÈ ~ ¯Ô'M natomiast spodziewam "Ciąg testowy". Jakieś pomysły, w których się mylę? Dzięki

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

możliwe duplikat [PHP Java AES CBC szyfrowania różne wyniki] (http : //stackoverflow.com/questions/10842509/php-java-aes-cbc-encryption-different-results) –

Odpowiedz

15

EDIT: Ponieważ Java 8 Java obejmuje obecnie akceptowalny klasę Base64, java.util.Base64.


Linia ta

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

wygląda źle. Zamiast tego należy użyć klas apache commons codec lub klasy Harder base64. Również domyślne wypełnienie używane przez mcrypt, zero padding, jest prawdopodobnie błędne i utrudnia korzystanie z wyników w innych językach. Sekcja komentarzy użytkowników dla mcrypt_encrypt web pages zawiera przykłady tego, jak to zrobić.

Oto mały przykład, który używa klas wspólnych Apache do odszyfrowania łańcucha.

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)); 
    } 

} 

ten produkuje następujące dane wyjściowe:

5465737420737472696e670000000000 

który gdy dekodowany jako ASCII i usunięcie zer daje Test string

+0

Zagłosowałem pierwszy, przed zamknięciem :) –

+0

Wielkie dzięki GregS. Bardzo dobrze wyjaśnione. – user812120

+0

Dzięki. Ale kluczem jest coś innego niż IV - klonowanie ich po prostu myli czytelników. –

Powiązane problemy