Rijndael 256 encryption: Java and .NET do not match
Asked Answered
S

1

9

I need to translate a powershell script with Rijandael encryption to Java. Here is the source powershell code:

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

For Java encryption I use bouncycastle and its RijndaelEngine with same parameters - CBC, 256 block size, zero padding. Here is my java code snippet:

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 arrays for secret key, initial vector and text to encrypt are absolutely the same:

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]

But the result array for powershell and Java differs:

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]

Please, can somebody help me to figure out what am I doing wrong in Java with bouncycastle? I was stack with it for whole day...

Spurry answered 4/4, 2013 at 7:20 Comment(0)
G
14

Your results are the same, as far as I can see - it's just that in Java, bytes are signed. (That's icky, but it doesn't affect the actual bits you're getting.)

If you add 256 to every negative value in the Java results, you'll see they're the same as the .NET code:

.NET:      241  100  194  184  166

Java:      -15  100  -62  -72  -90

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

(etc)

Alternatively, just print out the unsigned hex representation of the two byte arrays - or even base64-encode them - and you'll see they're the same.

Gokey answered 4/4, 2013 at 7:23 Comment(1)
Instead of adding to only negative values, you can also modulo: (val+256)%256Arroba

© 2022 - 2024 — McMap. All rights reserved.