如何解决reactJS中实现加解密OpenSSL和zlib
我的 PHP 代码有 2 个函数,其中使用 openSSL 进行加密和解密,实际上在我重构它之前,我将 openSSL 结果编码为 base64,导致它太长我更改为使用 zlib (gzdeflate,gzinflate) 然后将最后的结果转换为十六进制。
$secret_key = 'thisIsK3y';
$secret_iv = 'tHis1s1v';
$output = false;
$encrypt_method = "AES-256-CBC";
$key = hash( 'sha256',$secret_key );
$iv = substr( hash( 'sha256',$secret_iv ),16 );
$action = 'e';
$string = "33f6f1d3ebe5b9da5fd0e3a1c7dd71c6e484be914731cf96adac0c00" //decrypted = "test"
if( $action == 'e' )
{
$output = bin2hex(gzdeflate( gzdeflate(openssl_encrypt( $string,$encrypt_method,$key,$iv ),9),9) );
}
else if( $action == 'd' )
{
if (!empty($string))
$output = openssl_decrypt( gzinflate(gzinflate(pack("H*",$string ) ) ),$iv );
}
echo $output; // output : "test",it's working fine on PHP
然后我尝试在 React 上将语言转换为 JS 并制作了简单的工具,这是我目前的 JS 代码,:
let secret_key = "thisIsK3y";
let secret_iv = "tHis1s1v";
var output = false;
let encrypt_method = "AES-256-CBC";
let key = String(sha256(secret_key)).toString(Hex).substr(0,32);
let iv = String(sha256(secret_iv)).toString(Hex).substr(0,16);
if (action == 'd') { // Decryption
let enc = gzinflate(gzinflate(hex2bin(string)));
enc = enc.toString(Utf8);
let decrypted = AES.decrypt(enc,Utf8.parse(key),{
iv: Utf8.parse(iv),}).toString(Utf8);
console.log('sss',hex2bin('33f6f1d3ebe5b9da5fd0e3a1c7dd71c6e484be914731cf96adac0c00'));
debugger;
output = decrypted;
}
我将 gzinfalte、gzdeflate、hex2bin、bin2hex 方法拆分为另一个名为 string.js 的 JS 文件并导入了一些包 CryptoJS 和 PakoJS
string.js 包含一些这样的方法:
export function gzdeflate(str) {
return pako.deflateraw(str);
}
export function gzinflate(str) {
return pako.inflateraw(str);
}
export function bin2hex(s) {
let i
let l
let o = ''
let n
s += ''
for (i = 0,l = s.length; i < l; i++) {
n = s.charCodeAt(i)
.toString(16)
o += n.length < 2 ? '0' + n : n
}
return o
}
export function hex2bin(hex) {
let bytes = [],str;
for(var i=0; i< hex.length-1; i+=2){
bytes.push(parseInt(hex.substr(i,2),16));
}
str = String.fromCharCode.apply(String,bytes);
return str;
}
console.log(hex2bin('33f6f1d3ebe5b9da5fd0e3a1c7dd71c6e484be914731cf96adac0c00'));
但是,当我尝试将二进制文件转换为 gzinflate 时,它显示错误
console.log(gzinflate(gzinflate(hex2bin(33f6f1d3ebe5b9da5fd0e3a1c7dd71c6e484be914731cf96adac0c00))))
无法读取未定义的属性“密文”
当我尝试更改 secret_key 和 iv 时出现错误:
let secret_key = 'ffffffffffffffffffffffff{Curi}ty';
let secret_iv = 'ffffffffffffffffffffffff{Curi}ty';
错误:无效的存储块长度
有人可以帮我吗?
解决方法
我不是 PHP 专家,但我有其他人建议 PHP 可能会为您截断一些键。
我建议确保密钥生成函数在两种语言中对您的行为相同,并确保它们都只有 32 个字节长。
我想指出我在您的代码中看到的另一个问题。虽然它会起作用,但您正在降低加密的安全性。
let key = String(sha256(secret_key)).toString(Hex).substr(0,32);
任何时候您将一个 32 字节的二进制值转换为 HEX,然后只使用 16 进制输出的 32 个字符,您就显着降低了密钥的强度。找到一种保留为字节值的方法。
您正在尝试创建一个 256 位的密钥(32 个字节,每个字节有 256 个可能的值)。您实际上是在创建一个 32 个字符的字符串,并且每个字符只有 16 个可能的值 (0-1a-f)。您已将加密密钥的密钥安全性从预期的 256^32 (1.1E77) 更改为 16^32 (3.4E38)。
找到一种使用 SHA256 产生的字节值的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。