Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rijndael 256 encryption: Java and .NET do not match

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...

like image 352
anka976 Avatar asked Apr 04 '13 07:04

anka976


People also ask

What is AES in Java?

AES, Advanced Encryption Standard is a block ciphertext encryption and decryption algorithm that processes a block of 128 bits of data using secret keys of 128, 192, or 256 bits. We will also discuss how this algorithm can be implemented using the Java programming language.


1 Answers

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.

like image 74
Jon Skeet Avatar answered Sep 17 '22 09:09

Jon Skeet