2013-02-13 12 views
5

Rapido che mi ha evitato finora (lunga notte). Sto confrontando AES256 in PHP vs Java e notando discrepanze. Si prega per semplicità di ignorare la chiave ascii e la null IV, quelli saranno sostituiti in produzione. Ma ho bisogno di superare questa prima e non riesco a capire dove sto sbaglia:AES256 su Java vs PHP

PHP:

echo base64_encode(
    mcrypt_encrypt(
     MCRYPT_RIJNDAEL_128, 
     "1234567890ABCDEF1234567890ABCDEF", 
     "This is a test", 
     MCRYPT_MODE_CBC, 
     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 
    ) 
); 

Java

byte[] key = "1234567890ABCDEF1234567890ABCDEF".getBytes("UTF-8"); 
byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv); 
SecretKeySpec newKey = new SecretKeySpec(key, "AES"); 
Cipher cipher = Cipher.getInstance("AES"); 
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec); 
byte[] results = cipher.doFinal("This is a test".getBytes("UTF-8")); 

return Base64.encodeToString(results,Base64.DEFAULT); 

uscita PHP: uscita 0KwK+eubMErzDaPU1+mwTQ==

Java : DEKGJDo3JPtk48tPgCVN3Q==

Non proprio quello che mi aspettavo o_O!

Ho anche provato MCRYPT_MODE_CBC, MCRYPT_MODE_CFB, MCRYPT_MODE_ECB, MCRYPT_MODE_NOFB, ecc .. nessuno di loro ha prodotto la stringa Java.

+1

Avete provato a cambiare 'Cipher.getInstance (" AES ");' a 'Cipher.getInstance (" AES/CBC/NoPadding ");' –

+0

Yezzir, "AES/CBC/NoPadding" produce IllegalBlockSizeException: dati non bloccati dimensione allineata. "AES/CBC/PKCS5Padding" produce "DEKGJDo3JPtk48tPgCVN3Q ==", così come "AES/CBC/PKCS7Padding". –

+0

Questo è stato stupido da parte mia, senza padding devi essere sicuro che stai fornendo un multiplo della dimensione del blocco. Pubblicherò una risposta con quella che credo sia la soluzione. –

risposta

1

PHP calcola i byte di input con \0 per renderlo un multiplo della dimensione del blocco. L'equivalente in Java sarebbe questo (supponendo che la stringa che si desidera crittografare è in data):

Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
int blockSize = cipher.getBlockSize(); 

byte[] inputBytes = data.getBytes(); 
int byteLength = inputBytes.length; 
if (byteLength % blockSize != 0) { 
    byteLength = byteLength + (blockSize - (byteLength % blockSize)); 
} 

byte[] paddedBytes = new byte[byteLength]; 

System.arraycopy(inputBytes, 0, paddedBytes, 0, inputBytes.length); 

cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec); 
byte[] results = cipher.doFinal(paddedBytes); 

come un avvertimento per questo - a base zero padding non è desiderata. Non c'è modo di determinare la differenza tra i caratteri \0 alla fine della stringa e il riempimento effettivo. È preferibile utilizzare PKCS5Padding, ma otterrai risultati diversi in PHP. Chiediti se hai bisogno della crittografia multipiattaforma come questa.

+0

Il codice sopra riportato produce 0KwK + eubMErzDaPU1 + mwTQ == –

+0

Non è quello che stai cercando? Gratta che - non ho visto la risposta accettata –

+0

È sicuramente =) –