I have two system which are sharing a user database, so authentication needs to be the same.
The passwords are currently encrypted using C#'s Cryptography.Rijndael
(NB not RijndaelManaged). Using a custom key and iv (initialisation vector). (CBC mode and Pkcs7 padding)
The C# encryption is as follows:
Rijndael alg = Rijndael.Create();
alg.Key = key;
alg.IV = IV;
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(clearData, 0, clearData.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();
key
is 256 bits (32 bytes) and iv
(initialisation vector) is 128 bits (16 bytes). The block size is 128 bits (16 bytes).
key and iv are a byte arrays from a base64 strings via:
byte[] key = Convert.FromBase64String(base64Key);
byte[] iv = Convert.FromBase64String(base64IV);
NB I have no control on the C# code (legacy system).
On the javascript based system I have to encrypt the passwords exactly the same way. I've tried using node crypto-js
to no avail. my code looks something like this:
var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(password), keyCodeWords, {
iv: ivCodeWords,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
keyCodeWords and ivCodeWords are CryptoJS code words from the same base64 key and iv as follows:
var keyCodeWords = CryptoJS.enc.Base64.parse(base64Key);
var ivCodeWords = CryptoJS.enc.Base64.parse(base64IV);
The encryption does work (in the sense that I can encrypt and then decrypt to get the same value). However, the issue is that the encrypted value ( encrypted.ciphertext
) is not the same as the C# one, so I'm unable to authenticate.
The comparison is done base comparing the base64 encrypted output strings.
How do I make crypto-js (or any other javascript encryption library) consistent with C# Rijndael?
The code works correctly... Your problem is probably in the handling of the password/IV in C# or in Javascript... In C#: https://ideone.com/APC4MM and in Javascript: https://jsfiddle.net/jjwy5472/
I've used in both cases the same password:
byte[] key = new byte[]
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
};
byte[] iv = new byte[]
{
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
};
the plaintext is
"Hello world! This is a wonderful day! àèéìòù"
and in both cases the resulting encrypted text is
aa429aa5c1c928b86d81b43ff3fb6cc46f24cc73957bc7c00829357bf441eb3be9cf8aef2ff6f819f9b95c69886b169b6959c4f7ece0620c6a28f849516adee9
But note that the encrypted
variable in Javascript is a complex object, containing various properties with various versions of your encrypted data. encrypted.toString()
returns the base64 version of the encrypted data, encrypted.ciphertext
is a WordArray
(the equivalent of CryptoJS of byte[]
), and encrypted.ciphertext.toString()
is the hex version of it (equivalent to doing BitConverter.ToString(encryptedData).Replace("-", "").ToLowerInvariant()
in C#).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.