最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - OpenSSL Encrypt-Decrypt with CryptoJS - Stack Overflow

programmeradmin4浏览0评论

I have a problem to generate encryption in JS, I've the encryption generator in PHP like this :

$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;

then I tried to translanguage to JS on React using CryptoJS :

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));
}

then the alert show me this encryption : fd0337c029ad25c240316a1d61db9144, then I try to decrypt in my php.but it's show me plain text seems like non-printable ascii

b"}¦7▀À4█ÍØ█ù6ÒM§Ú¡]ÙW[¸^8"

and there is PHP notice :

PHP Notice: iconv(): Detected an illegal character in input string in /var/www/html/blabla/vendor/symfony/var-dumper/Dumper/AbstractDumper.php on line 203

Anyone can help me out ?

I have a problem to generate encryption in JS, I've the encryption generator in PHP like this :

$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;

then I tried to translanguage to JS on React using CryptoJS :

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));
}

then the alert show me this encryption : fd0337c029ad25c240316a1d61db9144, then I try to decrypt in my php.but it's show me plain text seems like non-printable ascii

b"}¦7▀À4█ÍØ█ù6ÒM§Ú¡]ÙW[¸^8"

and there is PHP notice :

PHP Notice: iconv(): Detected an illegal character in input string in /var/www/html/blabla/vendor/symfony/var-dumper/Dumper/AbstractDumper.php on line 203

Anyone can help me out ?

Share Improve this question edited Nov 10, 2020 at 15:59 Roby Firnando Yusuf asked Nov 10, 2020 at 15:53 Roby Firnando YusufRoby Firnando Yusuf 4214 silver badges13 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

If the PHP code is executed with the plaintext $string = "test"; then the encryption part provides:

MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09

Regarding the PHP code the following should be noted:

  1. The encryption process Base64 encodes twice. Once explicitly with base64_encode, once implicitly by default (s. openssl_encrypt, 4th parameter). This redundancy is not necessary, i.e. one of the two Base64 encodings should be removed. Analogous for decryption.
  2. The hash function returns by default the data hex encoded in lower case. Thus $key is 64 bytes in size. For AES-256 OpenSSL implicitly uses only the first 32 bytes.

The CryptoJS code you posted could be modified as follows to implement this functionality (JavaScript):

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 = Sha256(secret_key).toString(Hex).substr(0,32); // Use the first 32 bytes (see 2.)
var iv = Sha256(secret_iv).toString(Hex).substr(0,16);

// Encryption
var output = AES.encrypt("test", Utf8.parse(key), {
            iv: Utf8.parse(iv),
   }).toString(); // First Base64 encoding, by default (see 1.)

var output2ndB64 = Utf8.parse(output).toString(Base64); // Second Base64 encoding (see 1.)
console.log(output2ndB64); // MWNjdVlVL1hBWGN2UFlpMG9yMGZBUT09

// Decryption
var decrypted = AES.decrypt(output, Utf8.parse(key), {
            iv: Utf8.parse(iv),
   }).toString(Utf8); 
console.log(decrypted); // test
<script src="https://cdnjs.cloudflare./ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

taking into account the two points mentioned above for the PHP code. Like the hash function in the PHP code, toString(Hex) also uses lower case letters (so no conversion is necessary in this respect).

Note that in practice a static IV must not be used for security reasons. Instead, the IV should be newly generated for each encryption and sent to the recipient along with the ciphertext (the IV isn't secret). Also, using SHA256 as a key derivation function is not very secure.

发布评论

评论列表(0)

  1. 暂无评论