2011-11-10 10 views
5

Per determinati motivi, devo implementare Rijndael de/compression con un blocco di 256 bit anziché AES che utilizza una dimensione di blocco di 128 bit (motivo: i dati vengono crittografati in PHP utilizzando Rijndael ...).Come crittografare o decrittografare con Rijndael e un blocco di dimensioni di 256 bit?

Come posso modificare la dimensione del blocco per una cifra?

Se ottengo un codice con "RIJNDAEL/CFB/PKCS5Padding" e provo a inizializzare un IV con 256 bit, ottengo un'eccezione, perché la dimensione del blocco è di soli 128 bit.

+0

Probabilmente dovrete per assicurarsi di avere le classi di crittografia illimitato Java installato JCE . Non fanno parte della tipica distribuzione standard di Java perché sono illegali in alcuni paesi. – Romain

+0

li hanno già. non riesco ancora a scoprire come ottenere un oggetto cifrato con il blocco richiesto – Laures

+0

Quindi credo che @GregS abbia la risposta. Avevo creduto che Rijndael-256 fosse parte di JCE Unlimited Providers, ma sono abituato ad usare Java in qualche modo personalizzato della mia azienda - che ha un provider JCE per questo, ma potrebbe essere un'implementazione privata. – Romain

risposta

13

Non esiste alcun supporto in nessuno dei provider Sun JCE per qualcosa di diverso da Rijndael con il blocco a 128 bit: questo è l'algoritmo AES. Per ottenere rijndael con il blocco a 256 bit dovrai andare da qualche altra parte. Suggerisco la libreria Bouncycastle java. La classe RijndaelEngine ha un costruttore che accetta una dimensione di blocco in bit. La maggior parte delle persone trova la classe PaddedBufferedBlockCipher più comoda quando viene utilizzata con un'adeguata imbottitura, ad es.

PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new PKCS7Padding()); 
0

Nota che PHP mcrypt utilizza imbottitura zero byte in modo new ZeroBytePadding() dovrebbe essere usato al posto di new PKCS7Padding().

Sotto una implementazione completa utilizzando CBC e RIJNDAEL 256.

import org.bouncycastle.crypto.CipherParameters; 
import org.bouncycastle.crypto.InvalidCipherTextException; 
import org.bouncycastle.crypto.engines.RijndaelEngine; 
import org.bouncycastle.crypto.modes.CBCBlockCipher; 
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; 
import org.bouncycastle.crypto.paddings.ZeroBytePadding; 
import org.bouncycastle.crypto.params.KeyParameter; 
import org.bouncycastle.crypto.params.ParametersWithIV; 
import org.bouncycastle.util.encoders.Base64; 

public static String encryptWithAesCBC(String plaintext, String key, String iv) 
{ 
    try { 
     PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding()); 
     CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes()); 
     cipher.init(true, ivAndKey); 
     return new String(Base64.encode(cipherData(cipher, plaintext.getBytes()))); 
    } catch (InvalidCipherTextException e) { 
     throw new RuntimeException(e); 
    } 
} 

public static String decryptWithAesCBC(String encrypted, String key, String iv) 
{ 
    try { 
     byte[] ciphertext = Base64.decode(encrypted); 
     PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding()); 

     CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes()); 
     aes.init(false, ivAndKey); 
     return new String(cipherData(aes, ciphertext)); 
    } catch (InvalidCipherTextException e) { 
     throw new RuntimeException(e); 
    } 
} 

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws InvalidCipherTextException 
{ 
    int minSize = cipher.getOutputSize(data.length); 
    byte[] outBuf = new byte[minSize]; 
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0); 
    int length2 = cipher.doFinal(outBuf, length1); 
    int actualLength = length1 + length2; 
    byte[] cipherArray = new byte[actualLength]; 
    for (int x = 0; x < actualLength; x++) { 
     cipherArray[x] = outBuf[x]; 
    } 
    return cipherArray; 
} 

private String md5(String string) 
{ 
    try { 
     java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); 
     byte[] array = md.digest(string.getBytes()); 
     StringBuffer sb = new StringBuffer(); 
     for (int i = 0; i < array.length; ++i) { 
      sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3)); 
     } 
     return sb.toString(); 
    } catch (java.security.NoSuchAlgorithmException e) { 
     throw new RuntimeException(e); 
    } 
} 

Quando si utilizza CFB, PaddedBufferedBlockCipher dovrebbe essere sostituito da quanto segue:

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256),8), new ZeroBytePadding()); 
// PHP mcrypt uses a blocksize of 8 bit for CFB 

Usage:

String salt = "fbhweui3497"; 
String key = md5(salt); 
String iv = md5(md5(salt)); 

String encrypted = encryptWithAesCBC("text to encript", key, iv); 

String decrypted = decryptWithAesCBC(encrypted, key, iv); 
+1

Potete fornire md5() per favore? String md5 (String input) { \t \t String result = input; \t \t MessageDigest md; \t \t try { \t \t \t md = MessageDigest.getInstance ("MD5"); \t \t \t md.update (input.getBytes()); \t \t \t BigInteger hash = new BigInteger (1, md.digest()); \t \t \t result = hash.toString (16); \t \t \t while (risultato.lunghezza() <32) {// 40 per SHA-1 \t \t \t \t risultato = "0" + result; \t \t \t} \t \t} catch (NoSuchAlgorithmException e) { \t \t \t e.printStackTrace(); \t \t} \t \t risultato di ritorno; \t} Sopra metodo che dia, "java.lang.IllegalArgumentException: Chiave non lunghezza 128/160/192/224/256 bit." – Krish

+0

@Krish Ho appena aggiunto alla risposta l'implementazione md5. –

Problemi correlati