【发布时间】:2017-07-30 20:27:51
【问题描述】:
我正在加密以前用 base64 编码的东西。
步骤如下:
1. 用base64编码纯(可读)文本
2. 使用 CryptoJS 使用 DES/CBC/PKCS7PADDING 加密 base64 编码文本
3.将第2步得到的信息重新编码成base64
这是我的 Javascript 代码:
function encryptDesCbcPkcs7Padding(message, key) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var iv = new Uint8Array(0);
var ivHex = CryptoJS.enc.Hex.parse(CryptoJS.enc.Utf8.parse(iv).toString(CryptoJS.enc.Hex));
var encrypted = CryptoJS.DES.encrypt(message, keyHex, { iv: ivHex, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted;//.toString(CryptoJS.enc.Utf8);
}
var plainText = "hola";
console.log("Plain text: ", plainText);
var base64Coded = window.btoa(plainText);
console.log("Base64 coded text: ", base64Coded);
var encrypted = encryptDesCbcPkcs7Padding(base64Coded, "12345678");
console.log("Encrypted: ", encrypted);
var finalEncrypted = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
console.log("Final encrypted: ", finalEncrypted);
alert("Final encrypted: " + finalEncrypted);
使用此代码,我得到了前面步骤加密的信息。
问题:我无法进行相反的步骤。我做错了什么?
这些是我用于反向的代码:
function decryptDesCbcPkcs7Padding(message, key) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var iv = new Uint8Array(0);
var ivHex = CryptoJS.enc.Hex.parse(CryptoJS.enc.Utf8.parse(iv).toString(CryptoJS.enc.Hex));
var decrypted = CryptoJS.DES.decrypt(message, keyHex, { iv: ivHex, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return decrypted.toString(CryptoJS.enc.Utf8);
}
var base64Decoded = CryptoJS.enc.Base64.parse(finalEncrypted).toString();
console.log("Base64 decoded", base64Decoded);
var decrypted = decryptDesCbcPkcs7Padding(base64Decoded, "12345678");
console.log("Decrypted: ", decrypted);
var finalDecrypted = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
console.log("Final encrypted: ", finalEncrypted);
alert("Final encrypted: " + finalEncrypted);
我无法让这段代码工作,我做错了什么?
【问题讨论】:
-
IV 部分的整两行根本没有任何意义。
iv必须是CryptoJS.enc.Utf8.parse(iv)中的字符串,但它是一个 Uint8Array。然后你用十六进制编码它只是为了立即用十六进制解码它。这没有意义。那么对于 CBC 模式,IV 必须为 128 位长,但出于某种原因,您尝试使用空 IV。 -
还要检查最后两个控制台/警报打印:也许您想打印 finalDecrypted?
-
@ArtjomB。我试图把它作为一个 empy IV。在 java 语言中,我用 new byte[8] 初始化它,我尝试在 JavaScript 中做同样的事情。 (Empty 或 zeroIV): IvParameterSpec zeroIv = new IvParameterSpec(new byte[8]);
-
然后使用
var ivHex = CryptoJS.lib.WordArray.create([0, 0]);二进制数据表示为32位字,你需要其中两个。请记住,使用固定的 IV 值是不安全的。 IV不需要是秘密的,它只需要是不可预测的。因此,您应该始终生成一个随机 IV 并将其与密文一起发送。 -
谢谢@ArtjomB。我做了你建议的改变。但是反向得到的信息还是不一样的。 “finalDecrypted”变量应该反过来又得到“hola”
标签: javascript encryption cryptojs