I'm encrypting strings before sending to a 3rd party API that requires Triple DES encryption in ECB mode with PKCS#5 padding. They have given me a sample string to encrypt of
www.society.com|1084470043000|memberaccess
and a sample key of
92f2f81930b5afb056630afb02f2f8b1
The resulting encrypted string should match
uQlYYov+XlVEHL0JBpvt15FeJxt+fXgjs9KLJHH5XsUd80emx5Nn5kSaCXxhQId/
But the string I'm receiving is
U2FsdGVkX19/IR4A9cm+duXf3vhnmnuyJtXFVWJi/Ptqib7g5gOANppYXh+mTQ8tcenO58a5FxnFVxRq1PUETA==
I'm using these libraries
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/crypto-js.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/tripledes.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/mode-ecb.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9/pad-pkcs7.js"></script>
And this is my code
var encrypted = CryptoJS.TripleDES.encrypt("www.society.com|1084470043000|memberaccess" , "92f2f81930b5afb056630afb02f2f8b1", {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
I realize that I'm specifying PKCS#7 instead of PKCS#5 but I haven't found a library for PKCS#5.
My question is whether it is possible to meet their requirements using CryptoJS and if not, are there any other javascript solutions available?
My fiddle
https://jsfiddle.net/dwc6zb89/2/
I don't spend enough time in cryptography to give you a good answer on whether it's base64 or not. I believe so because I have a block of c# code that I've written that produces nearly the correct result. It's a few characters off. I'm continuing to compare the two to see what my c# code is doing that the javascript is not.
public static string Encrypt(string toEncrypt, bool useHashing)
{
var key = "92f2f81930b5afb056630afb02f2f8b1";
var iso8859_1 = System.Text.Encoding.GetEncoding("iso-8859-1");
var keyArray = Convert.FromBase64String(iso8859_1.GetString(iso8859_1.GetBytes(key)));
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
//Always release the resources and flush data
// of the Cryptographic service provide. Best Practice
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0,
toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
Update:
I feel like I'm maddeningly close. By converting my key using the following
var encryptedKey = CryptoJS.enc.Base64.parse(key);
I am able to generate an encrypted value that is only a few characters off from the sample the vendor has given me. This is my current fiddle.
https://jsfiddle.net/uv8z2mrc/1/
Update:
I had two issues.
I needed to base 64 encrypt my key before using it like so.
var encryptedKey = CryptoJS.enc.Base64.parse(key);
The vendors documentation was wrong and the value to encrypt was supposed to be use an address of .org instead of .com. GRRR!
From the CryptoJS docs:
For the key, when you pass a string, it's treated as a passphrase and used to derive an actual key and IV. Or you can pass a WordArray that represents the actual key. If you pass the actual key, you must also pass the actual IV.
You should hex decode the key to a word array and also give a 16 byte IV set to all zero bytes. The IV is not used by ECB, but please specify it none-the-less. Otherwise the key will be derived from the string, which will obviously lead to incorrect results.