I am using JavaScript to encrypt and php to decrypt the string and vice versa but the problem is that on both the platforms the output being generated is different say If I encrypt a string "abc" on both the platforms they will produce different results although I am sure my encryption is correct because the string I am encrypting is decrypted in same language.
I understands that in this case there has to be something different in key or iv but do not know what it
Javascript code to encrypt string
var encrypted = CryptoJS.TripleDES.encrypt("Message", "SecretPassphrase");
console.log(encrypted);console.log(String(encrypted));
var text = "<some plain text goes here>";
var key = "00f74597de203655b1ebf5f410f10eb8";
var useHashing = true;
if (useHashing) {
key = CryptoJS.MD5(key).toString();
key += key.substring(1, 16);
console.log(key);
}
var textWordArray = CryptoJS.enc.Utf16.parse(text);
var keyHex = CryptoJS.enc.Hex.parse(key);
var iv = String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0) + String.fromCharCode(0);
var ivHex = CryptoJS.enc.Hex.parse(iv);
console.log('hexadecimal key: ' + keyHex + '\n');
console.log('iv: ' + iv + '\n');
console.log('hexadecimal iv: ' + ivHex + '\n');
var options = {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: ivHex
};
var encrypted = CryptoJS.TripleDES.encrypt(textWordArray, keyHex, options);
var base64String = encrypted.toString();
console.log('base64: ' + base64String + '\n');
var decrypted = CryptoJS.TripleDES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(base64String)
}, keyHex, options);
console.log('decrypted: ' + decrypted.toString(CryptoJS.enc.Utf16));
PHP code to encrypt string
//Generate a key from a hash
$key = md5(utf8_encode("00f74597de203655b1ebf5f410f10eb8"), true);
//Take first 8 bytes of $key and append them to the end of $key.
$key .= substr($key, 0, 8);
//Padding for 3DES
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($value);
$pad = $blockSize - ($len % $blockSize);
$value .= str_repeat(chr($pad), $pad);
//Generating iv for 3DES
$iv = chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0) . chr(0);
//Encrypt data
$encData = mcrypt_encrypt(MCRYPT_3DES, $key, $value, MCRYPT_MODE_CBC, $iv);
$value = base64_encode($encData);
Example If I encrypt the string "admin" from javascript it gives me "U2FsdGVkX1+y/zo1FJEZZ0aqPMQuwilOydbJjzIKpYw="
Where as php give me "AzZFzbnwp2Y="
Note I am using CryptoJSv3 plugin for triple DES*
MD5 produces output of 128 bit, but a Triple DES key should be 192 bit long. That is why your PHP code copies the first 64 bits of the produced hash to the back. PHP and CryptoJS both use the EDE and this key copy leads to the key layout of K1 || K2 || K1
.
You can do the same thing in CryptoJS. Since CryptoJS uses a WordArray
to manage binary data internally as words of 32 bit, you can directly copy the first two words to the back of the internal array.
var pt = "admin";
document.querySelector("#pt").innerHTML = pt;
var key = "00f74597de203655b1ebf5f410f10eb8";
key = CryptoJS.MD5(key);
// copy 3DES subkey 1 to the last 64 bit to make a full 192-bit key
key.words[4] = key.words[0];
key.words[5] = key.words[1];
// create a 64-bit zero filled
var iv = CryptoJS.lib.WordArray.create(64/8);
var encrypted = CryptoJS.TripleDES.encrypt(pt, key, {iv: iv});
var encryptedBase64 = encrypted.toString();
document.querySelector("#enc").innerHTML = encryptedBase64;
var ct = {
ciphertext: CryptoJS.enc.Base64.parse(encryptedBase64)
};
var decrypted = CryptoJS.TripleDES.decrypt(ct, key, {iv: iv});
document.querySelector("#dec").innerHTML = decrypted.toString(CryptoJS.enc.Utf8);
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/tripledes.js"></script>
<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/md5.js"></script>
<p>Expected: "AzZFzbnwp2Y="<br/>Got: "<span id="enc"></span>"</p>
<p>Expected: "<span id="pt"></span>"<br/>Got: "<span id="dec"></span>"</p>
This code is not very secure for those reasons: