我的 js 中有这段代码:
export const encrypt = (data, key) => {
const encrypted = CryptoJS.AES.encrypt(
JSON.stringify(data),
key
).toString();
return encrypted;
};
但是当我在 Laravel 后端解密它时:
Route::post('/decrypt', function (Request $request) {
try{
$encrypted = $request->input("data");
Crypt::decrypt($encrypted);
}
catch(DecryptException $e) {
dd("error", $e);
}
});
这给了我 DecryptException“有效负载无效”
嗯...加密世界非常棘手,所以永远不要认为任何事情都是理所当然的。虽然使用相同的工具加密/解密有些微不足道,但在不同的系统上执行相同的操作可能会发现非常麻烦。
在这里,假设所有元素都已就位(正确安装,正确配置...!),问题可能出在
data
或 key
。
正如@Kris所指出的,您应该检查“双方的密钥是否相同”。乍一看这似乎很明显......但事实并非如此。
实际上,在加密/解密之前,CryptoJS 首先检查“key”是真实密钥还是明文密码(称为密码短语)。如果是后者,则它将明文密码转换为密钥,然后处理数据。再次...什么类型的转换?多长的钥匙?这完全取决于您的配置以及版本的默认值。通常,默认密钥大小为 256。
现在,我在您的后端示例中没有看到任何密码设置,但您应该检查它是否以与 CryptoJS 相同的方式处理密钥。如果您有控制权,您可以尝试在后端使用密钥复制 CryptoJS 的确切行为。但自己处理转换可能会真正节省时间,为 CryptoJS 提供一个它不会尝试处理的真实密钥。
加密数据通常是二进制的,不适合传输。安全传输数据的形式有很多种,其中使用最广泛的一种是 BASE64。这实际上就是 CryptoJS 在使用
toString()
时将数据转换为的内容,就像您一样。
现在,您必须检查您的后端是否期望这种格式,并正确处理它,无论是接口还是解密例程。例如,如果
Crypt::decrypt()
需要二进制数据,您应该首先对接收到的数据进行 BASE64 解码。