2013-04-04 36 views
7

Tôi cần dịch tập lệnh PowerShell với mã hóa Rijandael sang Java. Đây là mã nguồn PowerShell:Mã hóa Rijndael 256: Java và .NET không khớp với

[Reflection.Assembly]::LoadWithPartialName("System.Security") 
Add-Type -AssemblyName System.Web 

$sKy = "bbee9a3e8e44e28edb4539186d182aaa" 
$sIV = "131a68dc13160766f37dc931d7e518aa" 

$myRijndael = New-Object System.Security.Cryptography.RijndaelManaged 
$myRijndael.KeySize = 256 
$myRijndael.BlockSize = 256 
$myRijndael.Mode = [System.Security.Cryptography.CipherMode]::CBC 
$myRijndael.Padding = [System.Security.Cryptography.PaddingMode]::Zeros 

[byte[]] $key = [Text.Encoding]::ASCII.GetBytes($sKy) 
[byte[]] $IV = [Text.Encoding]::ASCII.GetBytes($sIV) 

$encryptor = $myRijndael.CreateEncryptor($key, $IV) 
$msEncrypt = new-Object IO.MemoryStream 
$csEncrypt = new-Object Security.Cryptography.CryptoStream $msEncrypt,$encryptor,"Write" 

$toEncrypt = [Text.Encoding]::ASCII.GetBytes("TEST_TEXT_TO_ENCODE") 

$csEncrypt.Write($toEncrypt, 0, $toEncrypt.Length) 
$csEncrypt.FlushFinalBlock() 
$encrypted = $msEncrypt.ToArray() 

Đối với mã hóa Java Tôi sử dụng BouncyCastle và RijndaelEngine của nó với cùng một thông số - CBC, 256 kích thước khối, zero padding. Dưới đây là đoạn mã java của tôi:

byte[] sessionKey = "bbee9a3e8e44e28edb4539186d182aaa".getBytes(); 
byte[] iv = "131a68dc13160766f37dc931d7e518aa".getBytes(); 
byte[] plaintext = "TEST_TEXT_TO_ENCODE".getBytes(); 

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
    new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding()); 

int keySize = 256/8; 

CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(sessionKey, 0, keySize), iv, 0, keySize); 

cipher.init(true, ivAndKey); 
byte[] encrypted = new byte[cipher.getOutputSize(plaintext.length)]; 
int oLen = cipher.processBytes(plaintext, 0, plaintext.length, encrypted, 0); 
cipher.doFinal(encrypted, oLen); 

Bytes mảng cho khóa bí mật, vector ban đầu và văn bản để mã hóa hoàn toàn giống nhau:

secret key: [98, 98, 101, 101, 57, 97, 51, 101, 56, 101, 52, 52, 101, 50, 56, 101, 100, 98, 52, 53, 51, 57, 49, 56, 54, 100, 49, 56, 50, 97, 97, 97] 
initial vector: [49, 51, 49, 97, 54, 56, 100, 99, 49, 51, 49, 54, 48, 55, 54, 54, 102, 51, 55, 100, 99, 57, 51, 49, 100, 55, 101, 53, 49, 56, 97, 97] 
text to encrypt: [84, 69, 83, 84, 95, 84, 69, 88, 84, 95, 84, 79, 95, 69, 78, 67, 79, 68, 69] 

Nhưng mảng kết quả cho PowerShell và Java khác:

powershell: [241, 100, 194, 184, 166, 85, 15, 212, 186, 220, 85, 136, 16, 194, 93, 11, 243, 245, 230, 207, 224, 88, 255, 153, 185, 9, 43, 78, 219, 138, 7, 222] 
java: [-15, 100, -62, -72, -90, 85, 15, -44, -70, -36, 85, -120, 16, -62, 93, 11, -13, -11, -26, -49, -32, 88, -1, -103, -71, 9, 43, 78, -37, -118, 7, -34] 

Xin vui lòng, ai đó có thể giúp tôi để tìm ra những gì tôi đang làm sai trong Java với bouncycastle? Tôi đã xếp chồng lên đó cả ngày ...

Trả lời

12

Kết quả của bạn giống như tôi thấy - chỉ trong Java, các byte được ký. (Đó là icky, nhưng nó không ảnh hưởng đến các bit thực tế bạn đang nhận được.)

Nếu bạn thêm 256 vào mọi giá trị âm trong kết quả Java, bạn sẽ thấy chúng giống như mã .NET. :

.NET:  241 100 194 184 166 

Java:  -15 100 -62 -72 -90 

Java+256: 241 100 194 184 166 
for -ve 

(vv)

ngoài ra, chỉ cần in ra các đại diện hex unsigned của hai mảng byte - hoặc thậm chí base64-mã hóa chúng - và bạn sẽ thấy chúng giống nhau.

+1

Thay vì chỉ thêm giá trị âm, bạn cũng có thể modulo: '' '(val + 256)% 256''' – dtech

+0

Cảm ơn rất nhiều, @Jon Skeet! – anka976