我使用JavaScript加密和php来解密字符串,反之亦然但问题是在两个平台上生成的输出是不同的说如果我加密字符串" abc"虽然我确信我的加密是正确的,但是我在两个平台上都会产生不同的结果,因为我加密的字符串是用同一种语言解密的。
我理解在这种情况下,键或iv必须有不同的东西,但不知道它是什么
用于加密字符串的Javascript代码
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代码
//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);
示例 如果我加密字符串&#34; admin&#34;从javascript它给我&#34; U2FsdGVkX1 + y / zo1FJEZZ0aqPMQuwilOydbJjzIKpYw =&#34;
php给我的地方&#34; AzZFzbnwp2Y =&#34;
注意我使用CryptoJSv3插件进行三重DES *
答案 0 :(得分:1)
MD5产生128位输出,但Triple DES密钥应为192位长。这就是为什么你的PHP代码将生成的哈希的前64位复制到后面的原因。 PHP和CryptoJS都使用EDE,这个密钥副本导致K1 || K2 || K1
的密钥布局。
你可以在CryptoJS中做同样的事情。由于CryptoJS使用WordArray
在内部管理二进制数据为32位字,因此您可以直接将前两个字复制到内部数组的后面。
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>
由于以下原因,此代码不是很安全: