2013-04-04 95 views
7

我需要將帶Rijandael加密的PowerShell腳本轉換爲Java。 這裏是源代碼的powershell:Rijndael 256加密:Java和.NET不匹配

[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() 

對於我使用BouncyCastle的爪哇加密及其與相同參數RijndaelEngine - CBC,256塊大小,零填充。這是我的Java代碼片斷:

的密鑰,初始向量和文本加密
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); 

字節數組是完全一樣的:

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] 

但結果數組的PowerShell和Java的區別:

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] 

請問,有人可以幫我弄清楚我在用bouncycastle在Java中做錯了什麼?我整天都在堆棧...

回答

12

你的結果就我所知,這只是在Java中,字節是有符號的。 (這是噁心的,但它不會影響你得到的實際位)。

如果你在Java結果中的每個負值上加256,你會發現它們和.NET代碼一樣:

.NET:  241 100 194 184 166 

Java:  -15 100 -62 -72 -90 

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

(ETC)

或者,只是打印出來的兩個字節數組的無符號十六進制表示 - 甚至是基於64位編碼他們 - 你會看到它們是相同的。

+1

而不是隻加負值,你也可以模:'(val + 256)%256''' – dtech 2013-04-04 07:40:12

+0

非常感謝@Jon Skeet! – anka976 2013-04-04 07:46:13