SJCL and .NET Rijndael giving different encryption results

988 views
Skip to first unread message

Anthony Wesley

unread,
Jan 3, 2013, 10:33:19 AM1/3/13
to sjcl-d...@googlegroups.com
Using the same encryption key and IV, I am getting varying results between the two encryption libraries.  

JS
var crypto = {
var encryptionKey, 
password, 
salt, 
cryptoParams = {
iterations: 1000,
keyLength: 256
};
function computeKey() {
// Added a func to misc that uses SHA1 rather than SHA256 as
// .NET's RFC2898DeriveBytes class uses SHA1
encryptionKey = sjcl.misc.pbkdf2_sha1(password, salt, cryptoParams.iterations, cryptoParams.keyLength);
encryptionKey = new sjcl.cipher.aes(encryptionKey);
}
function encrypt(message) {
// Will eventually use randomWords
var iv = sjcl.codec.hex.toBits('8291ff107e798a298291ff107e798a29');
// Only compute key once
if (encryptionKey === undefined) {
computeKey();
}
message = sjcl.codec.utf8String.toBits(message);
// Do the encryption
encryptedMessage = sjcl.mode.ccm.encrypt(encryptionKey, message, iv);
// Using this as a means to compare results
encryptedMessage = sjcl.codec.bytes.fromBits(encryptedMessage);
// Generally I will encode the bytes of the IV into encryptedMessage
// That is omitted here as just the result of the encryption-to-bytes
// already differs
return encryptedMessage;
}
return {
encrypt: encrypt
};
};

C#
public static string AESEncrypt(byte[] unencryptedData, byte[] encryptionKey)
{
// Same as var iv = sjcl.codec.hex.toBits('8291ff107e798a298291ff107e798a29');
byte[] initializationVector = new byte[] { 130, 145, 255, 16, 126, 121, 138, 41, 130, 145, 255, 16, 126, 121, 138, 41 };

// Encrypt the bytes.
byte[] encryptedData = AESEncrypt(unencryptedData, encryptionKey, initializationVector);

// Convert the bytes into a base 64 string.
string encryptedString = System.Convert.ToBase64String(encryptedData);
return encryptedString;
}

private static byte[] AESEncrypt(byte[] inputData, byte[] key, byte[] initializationVector)
{
// Create the object that will do the encryption or decryption.
using (SymmetricAlgorithm algorithm = Rijndael.Create())
{
// Set the key and initialization vector.
algorithm.Key = key;
algorithm.IV = initializationVector;

using (ICryptoTransform transform = algorithm.CreateEncryptor())
{
// Create a CryptoStream that we'll use to write to the memory stream. 
using (MemoryStream memoryStream = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
{
// Write the data to encrypt or decrypt it.
cryptoStream.Write(inputData, 0, inputData.Length);
cryptoStream.Close();

// Now get the encrypted or decrypted data from the MemoryStream. 
byte[] encryptedDecryptedData = memoryStream.ToArray();
return encryptedDecryptedData;
}
}
}
}

Anthony Wesley

unread,
Jan 3, 2013, 10:36:42 AM1/3/13
to sjcl-d...@googlegroups.com
I hit post too soon - should I expect identical results? I know AES is a particular variant of Rijndael with a fixed block size.  What can I consider changing so that the results are identical, if possible?  Basically I would like to be able to encrypt with either library and decrypt with the other.

I have some fairly large gaps in my understanding of encryption and am having trouble asking the right questions.  If they seem naive, I apologize.  

Anthony Wesley

unread,
Jan 3, 2013, 10:57:51 AM1/3/13
to sjcl-d...@googlegroups.com
I should also be clear that 
* The .NET Rijndael class does default to a block size of 128-bits
* The cipher mode is CBC
* The padding mode (?) is PKCS7


Andrew Smith

unread,
Jan 3, 2013, 4:09:07 PM1/3/13
to sjcl-d...@googlegroups.com
Hello Anthony.

It's a while since I coded any .net (I gave up on Microsoft when they released an operating system - Vista - which their own development tools would't run properly on…) and I never used the Crypto libraries when I did but looking through your code I can see a couple of problems.

Firstly the encryption you are carrying out with SJCL uses CCM which is an authenticated encryption mode. The .net code you have provided uses CBC mode, which is not, and is not the same thing

There is an msdn article here
which describes using .net for authenticated encryption. 

That appears to be the main issue with your code. Other points worth looking at once you have fixed that are:

There are specific AES classes in the .net crypto library so it would probably best to use those rather than the Rijndael classes, even if AES is Rijndael with a 128 bit block size.

I can't that you are using pbkdf2 on the .net side to generate a key from your password,

Also, my understanding is that SHA1 should not be used for any new software. Using SHA256 is preferable.

I hope that is enough to get you pointed in the right direction.

Kind Regards

Andrew Smith

On 3 Jan 2013, at 15:33, Anthony Wesley <awe...@gmail.com> wrote:

Rijndael

Anthony Wesley

unread,
Jan 4, 2013, 9:03:00 AM1/4/13
to sjcl-d...@googlegroups.com
I understand.  

Regarding key derivation, SJCL PBKDF2 with SHA1 is interopable with 

Once I decide on an implementation of AES with CCM, then I'll see if I can find a .NET library of PBKDF2-SHA256 that is interoperable with SJCL PBKDF2.  

Thank you so much for the clarification.  
-Tony

- Tony
Reply all
Reply to author
Forward
0 new messages