2011-11-10 37 views
5

Vì lý do nào đó, tôi cần triển khai Rijndael de/compression với khối 256 bit thay vì AES sử dụng kích thước khối 128 bit (lý do: dữ liệu được mã hóa bằng PHP bằng Rijndael ...).Làm thế nào để mã hóa hoặc giải mã bằng Rijndael và kích thước khối 256 bit?

Làm cách nào để thay đổi kích thước khối cho mật mã?

Nếu tôi chỉ nhận được mật mã với "RIJNDAEL/CFB/PKCS5Padding" và cố gắng khởi tạo IV với 256 bit, tôi nhận được ngoại lệ, vì kích thước khối chỉ là 128 bit.

+0

Có thể bạn sẽ phải đảm bảo bạn đã mã hóa các lớp không giới hạn Java JCE cài đặt . Chúng không phải là một phần của bản phân phối Java tiêu chuẩn điển hình bởi vì chúng là bất hợp pháp ở một số quốc gia. – Romain

+0

allready có chúng. vẫn không thể tìm ra cách để có được một đối tượng mật mã với khối yêu cầu – Laures

+0

Sau đó, tôi tin rằng @GregS có câu trả lời. Tôi đã tin Rijndael-256 là một phần của các nhà cung cấp không giới hạn JCE, nhưng tôi đã quen với việc sử dụng Java phần mềm tùy biến của công ty tôi - một nhà cung cấp JCE cho nó, nhưng nó cũng có thể được thực hiện riêng tư. – Romain

Trả lời

13

Không có hỗ trợ trong bất kỳ nhà cung cấp Sun JCE nào cho bất kỳ điều gì khác ngoài Rijndael với khối bit 128 bit: đây là thuật toán AES. Để có được rijndael với khối 256-bit, bạn sẽ phải đi đâu đó khác. Tôi đề nghị thư viện Bouncycastle java. Lớp RijndaelEngine có một hàm tạo chấp nhận kích thước khối theo bit. Hầu hết mọi người đều thấy lớp học PaddedBufferedBlockCipher thuận tiện hơn khi được sử dụng với đệm phù hợp, ví dụ:

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

Lưu ý rằng PHP Mcrypt sử dụng không byte đệm nên new ZeroBytePadding() nên được sử dụng thay vì new PKCS7Padding().

Thực hiện đầy đủ bằng cách sử dụng CBCRIJNDAEL 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); 
    } 
} 

Khi sử dụng CFB, PaddedBufferedBlockCipher nên thay thế bởi những điều sau đây:

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

Cách sử dụng:

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

Bạn có thể vui lòng cung cấp md5() không? Chuỗi md5 (đầu vào chuỗi) { \t \t Kết quả chuỗi = đầu vào; \t \t MessageDigest md; \t \t thử { \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 khi (kết quả.length() <32) {// 40 cho SHA-1 \t \t \t \t kết quả = "0" + kết quả; \t \t \t} \t \t} catch (NoSuchAlgorithmException e) { \t \t \t e.printStackTrace(); \t \t} \t \t kết quả trả về; \t} Đưa ra phương pháp trên, "java.lang.IllegalArgumentException: Độ dài khóa không 128/160/192/224/256 bit". – Krish

+0

@Krish Tôi vừa thêm vào câu trả lời cho việc triển khai md5. –

Các vấn đề liên quan