2013-02-13 85 views
5

Một cách nhanh chóng, điều đó đã tránh xa tôi (đêm dài). Tôi đang so sánh AES256 trong PHP so với Java và nhận thấy sự khác biệt. Xin vui lòng cho đơn giản bỏ qua các khóa ascii và null IV, những người sẽ được thay thế trong sản xuất. Nhưng tôi cần phải vượt qua đầu tiên này và không thể tìm ra nơi tôi đang erring:AES256 trên Java so với 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); 

PHP đầu ra: đầu ra 0KwK+eubMErzDaPU1+mwTQ==

Java : DEKGJDo3JPtk48tPgCVN3Q==

Không hoàn toàn là những gì tôi mong đợi o_O!

Tôi cũng đã thử MCRYPT_MODE_CBC, MCRYPT_MODE_CFB, MCRYPT_MODE_ECB, MCRYPT_MODE_NOFB, v.v. không ai trong số họ tạo chuỗi Java.

+1

Các bạn đã cố gắng thay đổi 'Cipher.getInstance ("AES"); 'cho' Cipher.getInstance ("AES/CBC/NoPadding"); ' –

+0

Yezzir, "AES/CBC/NoPadding" sản xuất IllegalBlockSizeException: Dữ liệu không chặn kích thước phù hợp. "AES/CBC/PKCS5Padding" tạo ra "DEKGJDo3JPtk48tPgCVN3Q ==", cũng như "AES/CBC/PKCS7Padding". –

+0

Đó là ngu ngốc của tôi, mà không có đệm bạn phải chắc chắn rằng bạn đang cung cấp một bội số của kích thước khối. Tôi sẽ đăng một câu trả lời với những gì tôi tin là giải pháp. –

Trả lời

1

PHP đệm byte đầu vào bằng \0 để làm cho nó trở thành bội số của kích thước khối. Tương đương trong Java sẽ được điều này (giả sử chuỗi bạn muốn mã hóa là trong 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); 

Như một lời cảnh báo này - không dựa trên đệm không mong muốn. Không có cách nào để xác định sự khác biệt giữa các ký tự \0 ở cuối chuỗi và phần đệm thực tế. Thay vào đó, tốt hơn nên sử dụng PKCS5Padding, nhưng bạn sẽ nhận được các kết quả khác nhau trong PHP. Hãy tự hỏi nếu bạn CẦN nền tảng mã hóa như thế này.

+0

Đoạn mã trên tạo ra 0KwK + eubMErzDaPU1 + mwTQ == –

+0

Đó không phải là những gì bạn đang tìm kiếm? Scratch rằng - không nhìn thấy câu trả lời được chấp nhận –

+0

Nó chắc chắn nhất là =) –