Javascript OpenSSL使用CryptoJS加密解密
我在JS中生成加密时遇到问题, 我在PHP中使用了如下加密生成器:Javascript OpenSSL使用CryptoJS加密解密,javascript,node.js,reactjs,encryption,cryptojs,Javascript,Node.js,Reactjs,Encryption,Cryptojs,我在JS中生成加密时遇到问题, 我在PHP中使用了如下加密生成器: $secret_key = 'thisIsK3y'; $secret_iv = 'tHis1s1v'; $output = false; $encrypt_method = "AES-256-CBC"; $key = hash( 'sha256', $secret_key ); $iv = substr( hash( 'sha256',
$secret_key = 'thisIsK3y';
$secret_iv = 'tHis1s1v';
$output = false;
$encrypt_method = "AES-256-CBC";
$key = hash( 'sha256', $secret_key );
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
if( $action == 'e' )
{
$output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
}
else if( $action == 'd')
{
$output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
}
return $output;
然后我尝试在React上使用CryptoJS将语言转换为JS:
import sha256 from "crypto-js/sha256";
import Base64 from "crypto-js/enc-base64";
import AES from "crypto-js/aes";
let secret_key = "thisIsK3y";
let secret_iv = "tHis1s1v";
let output = false;
let encrypt_method = "AES-256-CBC";
let key = sha256(secret_key);
let iv = String(sha256(secret_iv)).substr(0, 16);
if (action == "e") { // encrypt action
output = AES.encrypt("test", Utf8.parse(key), {
iv: Utf8.parse(iv),
}).toString();
alert(Base64.parse(output));
}
然后警报显示此加密:fd0337c029ad25c240316a1d61db9144,然后我尝试在我的php中解密。但它显示的纯文本似乎是不可打印的ascii
b} 阿尔法7▀À4█ÍØ█ù6ÒM§]W[1848]
还有一个注意事项:
PHP注意:iconv:在中的输入字符串中检测到非法字符
/var/www/html/blabla/vendor/symfony/var dumper/dumper/AbstractDumper.php
在线203
有人能帮我吗?如果PHP代码是用明文$string=test执行的;那么加密部分提供:
MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09
关于PHP代码,应注意以下几点:
加密过程Base64编码两次。一次显式使用Base64_编码,一次默认隐式编码。此冗余不是必需的,即应删除两个Base64编码中的一个。类似于解密。
默认情况下,该函数返回以小写形式编码的十六进制数据。因此,$key的大小为64字节。对于AES-256,OpenSSL仅隐式使用前32个字节。
您发布的CryptoJS代码可以进行如下修改以实现此功能:
var Sha256=CryptoJS.Sha256;
var Hex=CryptoJS.enc.Hex;
var Utf8=CryptoJS.enc.Utf8;
var Base64=CryptoJS.enc.Base64;
var AES=CryptoJS.AES;
var secret_key='thisIsK3y';
var secret_iv=‘tHis1s1v’;
var key=Sha256secret\u key.toStringHex.substr0,32;//使用前32个字节请参见2。
var iv=Sha256secret_iv.toStringHex.substr0,16;
//加密
var输出=AES.encryptest,Utf8.parsekey{
iv:Utf8.parseiv,
}.toString;//第一个Base64编码,默认情况下请参见1。
var output2ndB64=Utf8.parseoutput.toStringBase64;//第二个Base64编码请参见1。
console.logoutput2ndB64;//MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09
//解密
var decrypted=AES.decryptoutput,Utf8.parsekey{
iv:Utf8.parseiv,
}.toStringUtf8;
console.logdecrypted;//测试
如果使用明文$string=test执行PHP代码,则加密部分提供:
MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09
关于PHP代码,应注意以下几点:
加密过程Base64编码两次。一次显式使用Base64_编码,一次默认隐式编码。此冗余不是必需的,即应删除两个Base64编码中的一个。类似于解密。
默认情况下,该函数返回以小写形式编码的十六进制数据。因此,$key的大小为64字节。对于AES-256,OpenSSL仅隐式使用前32个字节。
您发布的CryptoJS代码可以进行如下修改以实现此功能:
var Sha256=CryptoJS.Sha256;
var Hex=CryptoJS.enc.Hex;
var Utf8=CryptoJS.enc.Utf8;
var Base64=CryptoJS.enc.Base64;
var AES=CryptoJS.AES;
var secret_key='thisIsK3y';
var secret_iv=‘tHis1s1v’;
var key=Sha256secret\u key.toStringHex.substr0,32;//使用前32个字节请参见2。
var iv=Sha256secret_iv.toStringHex.substr0,16;
//加密
var输出=AES.encryptest,Utf8.parsekey{
iv:Utf8.parseiv,
}.toString;//第一个Base64编码,默认情况下请参见1。
var output2ndB64=Utf8.parseoutput.toStringBase64;//第二个Base64编码请参见1。
console.logoutput2ndB64;//MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09
//解密
var decrypted=AES.decryptoutput,Utf8.parsekey{
iv:Utf8.parseiv,
}.toStringUtf8;
console.logdecrypted;//测试
非常感谢!所以iv应该是动态的,并且仍然有可能攻击此加密?两种代码都采用CBC模式。AES-CBC被认为是安全的,前提是一个密钥/iv对只使用一次,s。通常,这是通过为每个加密生成一个新的随机iv来确保的。此外,SHA256不应作为密钥派生函数应用,但更可靠的算法,例如CBC的一种替代方案是,它除了提供机密性外,还提供真实性和完整性。非常感谢!因此iv应该是动态的,并且仍然有可能攻击这种加密?两种代码都采用CBC模式。AES-CBC被认为是安全的,前提是一个密钥/iv对只使用一次,通常是通过为每次加密生成一个新的随机IV来确保。此外,SHA256不应作为密钥派生函数应用,但更可靠的算法(例如CBC的替代算法)是,它不仅提供机密性,还提供真实性和完整性。