OpenSSL与CryptoJS SHA256加密转换
OpenSSL and CryptoJS SHA256 encryption conversion
我的问题是较新版本的 OpenSSL 与 CryptoJS 的默认设置不兼容。
The default hash used by openssl enc for password-based key derivation
changed in 1.1.0 to SHA256 versus MD5 in lower versions.
https://unix.stackexchange.com/questions/344150/why-can-one-box-decrypt-a-file-with-openssl-but-another-one-cant/344586#344586
默认情况下,CryptoJS 使用 MD5 进行密钥派生。 OpenSSL 使用 MD5,但现在在 OpenSSL 版本 >=1.1.0 中它使用 SHA256。
因此,如果我将 -md md5
传递给 OpenSSL,CryptoJS 是兼容的:
echo "Hello World" | openssl enc -aes-256-cbc -md md5 -pass pass:"Secret Passphrase" -e -base64
输出:U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=
加密JS:
CryptoJS.AES.decrypt('U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);
输出:"Hello World"
但是现在如果我想使用 SHA256 而不是 MD5(删除 -md md5
):
echo "Hello World" | openssl enc -aes-256-cbc -pass pass:"Secret Passphrase" -e -base64
输出:U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=
加密JS:
CryptoJS.AES.decrypt('U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);
输出:空
如何告诉 CryptoJS 使用 SHA256 而不是 MD5 进行密钥派生?
CryptoJS "as-is" 似乎没有提供这种灵活性。这是因为 MD5 的使用被硬编码到用于从密码短语派生密钥的函数中。你可以看到它正在发生 here in OpenSSLKdf:
var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
KDF代表Key Derivation Function,创建时没有提供摘要。正如您在 its configuration options:
中看到的那样,EvpKDF.create()
本身确实具有不同类型摘要的可能性
cfg: Base.extend({
keySize: 128/32,
hasher: MD5,
iterations: 1
}),
也说明MD5是默认的
所有这些都意味着,如果您将第一行修改为以下内容,解密将起作用:
var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: C_algo.SHA256 }).compute(password, salt);
事实上,在您本地安装的模块中编辑(作为测试)该文件 cipher-core.js
后,您的最后一行代码确实产生了所需的 Hello World
.
我认为在不修改 CryptoJS 模块本身的情况下重现它的唯一方法是将模块中的整个代码块复制到您自己的代码中。
我的问题是较新版本的 OpenSSL 与 CryptoJS 的默认设置不兼容。
The default hash used by openssl enc for password-based key derivation changed in 1.1.0 to SHA256 versus MD5 in lower versions. https://unix.stackexchange.com/questions/344150/why-can-one-box-decrypt-a-file-with-openssl-but-another-one-cant/344586#344586
默认情况下,CryptoJS 使用 MD5 进行密钥派生。 OpenSSL 使用 MD5,但现在在 OpenSSL 版本 >=1.1.0 中它使用 SHA256。
因此,如果我将 -md md5
传递给 OpenSSL,CryptoJS 是兼容的:
echo "Hello World" | openssl enc -aes-256-cbc -md md5 -pass pass:"Secret Passphrase" -e -base64
输出:U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=
加密JS:
CryptoJS.AES.decrypt('U2FsdGVkX19aufvaqQQ89scaApBos6oFCyqPj7IKUFk=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);
输出:"Hello World"
但是现在如果我想使用 SHA256 而不是 MD5(删除 -md md5
):
echo "Hello World" | openssl enc -aes-256-cbc -pass pass:"Secret Passphrase" -e -base64
输出:U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=
加密JS:
CryptoJS.AES.decrypt('U2FsdGVkX1/5LLkFkTpawh1im4a/fCco5hS42cjn/fg=', 'Secret Passphrase').toString(CryptoJS.enc.Utf8);
输出:空
如何告诉 CryptoJS 使用 SHA256 而不是 MD5 进行密钥派生?
CryptoJS "as-is" 似乎没有提供这种灵活性。这是因为 MD5 的使用被硬编码到用于从密码短语派生密钥的函数中。你可以看到它正在发生 here in OpenSSLKdf:
var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
KDF代表Key Derivation Function,创建时没有提供摘要。正如您在 its configuration options:
中看到的那样,EvpKDF.create()
本身确实具有不同类型摘要的可能性
cfg: Base.extend({
keySize: 128/32,
hasher: MD5,
iterations: 1
}),
也说明MD5是默认的
所有这些都意味着,如果您将第一行修改为以下内容,解密将起作用:
var key = EvpKDF.create({ keySize: keySize + ivSize, hasher: C_algo.SHA256 }).compute(password, salt);
事实上,在您本地安装的模块中编辑(作为测试)该文件 cipher-core.js
后,您的最后一行代码确实产生了所需的 Hello World
.
我认为在不修改 CryptoJS 模块本身的情况下重现它的唯一方法是将模块中的整个代码块复制到您自己的代码中。