23

I'm encrypting some parameters in PHP using

 openssl("parameter", "AES-256-ECB", "client")

and I wish to decrypt in CryptoJS:

CryptoJS.AES.decrypt(parameter, "client", {mode: CryptoJS.mode.ECB}).toString(CryptoJS.enc.Utf8);

but it's throwing an empty string.

Any suggestions?

Loveen Dyall
  • 824
  • 2
  • 8
  • 20

3 Answers3

49

CryptoJS: PHP openssl encrypt -> javascript decrypt

PHP:

function CryptoJSAesEncrypt($passphrase, $plain_text){

    $salt = openssl_random_pseudo_bytes(256);
    $iv = openssl_random_pseudo_bytes(16);
    //on PHP7 can use random_bytes() istead openssl_random_pseudo_bytes()
    //or PHP5x see : https://github.com/paragonie/random_compat

    $iterations = 999;  
    $key = hash_pbkdf2("sha512", $passphrase, $salt, $iterations, 64);

    $encrypted_data = openssl_encrypt($plain_text, 'aes-256-cbc', hex2bin($key), OPENSSL_RAW_DATA, $iv);

    $data = array("ciphertext" => base64_encode($encrypted_data), "iv" => bin2hex($iv), "salt" => bin2hex($salt));
    return json_encode($data);
}

$string_json_fromPHP = CryptoJSAesEncrypt("your passphrase", "your plain text");

JS:

function CryptoJSAesDecrypt(passphrase,encrypted_json_string){

    var obj_json = JSON.parse(encrypted_json_string);

    var encrypted = obj_json.ciphertext;
    var salt = CryptoJS.enc.Hex.parse(obj_json.salt);
    var iv = CryptoJS.enc.Hex.parse(obj_json.iv);   

    var key = CryptoJS.PBKDF2(passphrase, salt, { hasher: CryptoJS.algo.SHA512, keySize: 64/8, iterations: 999});

        
    var decrypted = CryptoJS.AES.decrypt(encrypted, key, { iv: iv});

    return decrypted.toString(CryptoJS.enc.Utf8);
}

console.log(CryptoJSAesDecrypt('your passphrase','<?php echo $string_json_fromPHP?>'));

CryptoJS: javascript encrypt -> PHP openssl decrypt

JS:

function CryptoJSAesEncrypt(passphrase, plain_text){

    var salt = CryptoJS.lib.WordArray.random(256);
    var iv = CryptoJS.lib.WordArray.random(16);
    //for more random entropy can use : https://github.com/wwwtyro/cryptico/blob/master/random.js instead CryptoJS random() or another js PRNG

    var key = CryptoJS.PBKDF2(passphrase, salt, { hasher: CryptoJS.algo.SHA512, keySize: 64/8, iterations: 999 });

    var encrypted = CryptoJS.AES.encrypt(plain_text, key, {iv: iv});

    var data = {
        ciphertext : CryptoJS.enc.Base64.stringify(encrypted.ciphertext),
        salt : CryptoJS.enc.Hex.stringify(salt),
        iv : CryptoJS.enc.Hex.stringify(iv)    
    }
    
    return JSON.stringify(data);
}

PHP:

function CryptoJSAesDecrypt($passphrase, $jsonString){

    $jsondata = json_decode($jsonString, true);
    try {
        $salt = hex2bin($jsondata["salt"]);
        $iv  = hex2bin($jsondata["iv"]);          
    } catch(Exception $e) { return null; }

    $ciphertext = base64_decode($jsondata["ciphertext"]);
    $iterations = 999; //same as js encrypting 

    $key = hash_pbkdf2("sha512", $passphrase, $salt, $iterations, 64);

    $decrypted= openssl_decrypt($ciphertext , 'aes-256-cbc', hex2bin($key), OPENSSL_RAW_DATA, $iv);

    return $decrypted;

}

in mi tests I have used : github.com/sytelus/CryptoJS

MTK
  • 3,300
  • 2
  • 33
  • 49
  • This does not work if I use other algo such as AES-128-CBC, AES-192-CBC – vee Apr 07 '18 at 07:09
  • 5
    Here is the updated code from yours. It is also support all 128, 192, 256 for AES-CBC methods. https://gist.github.com/ve3/0f77228b174cf92a638d81fddb17189d I must thank you for this. – vee Apr 07 '18 at 17:02
  • Good job.I used the example only for the strongest encryption that can be used with Crypto.js (aes-256-cbc) – MTK Apr 07 '18 at 20:56
  • Hii, Your function is not work in my code for decrypt and encrypt cryptojs string so can you please help me how can i resolve this issue. – Gaurang Sondagar May 23 '19 at 07:18
  • 1
    @GaurangSondagar what mean for you "Your function is not work"? which of the functions does not work for you and what errors or what happend? Maybe you have different version of cryptojs ... in mi tests I have used : https://github.com/sytelus/CryptoJS – MTK May 23 '19 at 21:14
  • I have encrypt json data from angular7 using cryptojs and i send it to php api and i try to decrypt this code using above function but i am not able to decrypt it. So is there any wrong with above function or i need to try another way to decrypt code. please suggest me best way. – Gaurang Sondagar May 24 '19 at 04:03
  • For ex. my string is "U2FsdGVkX19Ih0C6uqwelqKLkqYmTZwtRtFRkxvd7DixPT2VYTLpBhZHplVIOw3L" and my password key is 123 so i am able to decrypt using above php function so can please check it and let me know above php functino is working or not. – Gaurang Sondagar May 24 '19 at 04:09
  • Hello @MTK, can you please provide me a proper solution that i explain before – Gaurang Sondagar Jun 12 '19 at 12:08
  • @GaurangSondagar . I'm very busy, but I'm trying to help you. Your string: `U2FsdGVkX19Ih0C6uqwelqKLkqYmTZwtRtFRkxvd7DixPT2VYTLpBhZHplVIOw3L` is the (original) real string or is the encrypted result base64 encoded ?. – MTK Jun 12 '19 at 12:55
  • Until you explain me about your string above ... I suggest to copy the js function `CryptoJSAesEncrypt()` above (the third function) to your project and use it for encrypt your string like that `var encrypted = CryptoJSAesEncrypt('123','your_string_here')` and use this result in your PHP to decrypt with the PHP function `CryptoJSAesDecrypt('123',$_POST['encrypted'])` (the last function) – MTK Jun 12 '19 at 20:43
  • @MTK "U2FsdGVkX19Ih0C6uqwelqKLkqYmTZwtRtFRkxvd7DixPT2VYTLpBhZHplVIOw3L" is my encrypted string using cryptojs, I applied cryptojs in angular and above string was encrypted in angular and try to decrypt in php but i am not able decryot above string in php, as i explain my encrypted string is this and key is 123 but i am not able to decrypt in php. So please suggest me proper way. – Gaurang Sondagar Jun 13 '19 at 04:09
  • The proper way is to use for decryption same parameters that you have used in encryption process: same algorithm (`aes-256-cbc` in above example) same number of iterations, same `key` (take care the `key` is not your '123'! '123' is your passphrase), same `iv`, same `salt`. SO if one of these are not the same the decryption process not work. I suggest you to copy the js function `CryptoJSAesEncrypt()` to your project and reencrypt the original .... Or to check manually each parameter described above in your angular framework and modfy these parameters in the PHP function `CryptoJSAesDecrypt` – MTK Jun 13 '19 at 11:19
  • In mi case I receive in php some like `{"ct":"8xoxUOfpF5ZkWkew98i2wA==","s":"0885fe94e83c9595a80840911f787abee86d5ebe9475e8c6c0912979a2f4e7eca9a2ed9773cf32f1c8652824526e49d3e26b","iv":"ef810cbf77a372f4904e2810353a8ba5"}` where `ct:` is the encrypted text `s:` is the salt and `iv:` is the iv in your case if I try to Base64 decode your string the result is: `Salted__H@şşŹ˘Ś&M-FŃQÝě8ą==a2éGŚUH; Ë`. So in conclusion you cannot use the function above for decrypt because the parameters are not in correct format to use with the above functions – MTK Jun 13 '19 at 11:50
  • 1
    Solutions: 1. Try to find some function in PHP that are compatible with angular (unfortunately I dont work with angular). 2. Use js function above for reencrypt your original data and then must be working. (But with one condition: if people from angular have not changed the original code for CryptoJS see https://github.com/sytelus/CryptoJS/tree/master/rollups ) – MTK Jun 13 '19 at 11:53
  • Great Job , I used the code in one of my solutions. Thanks. – Sujeet malvi Apr 06 '22 at 11:30
1

PHP Encryption

   function encryptPhp($string) {
            $encrypt_method="AES-256-CBC";
            $secret_key='secret_key';
            $secret_iv='secret_iv';
            $key=hash('sha256',$secret_key);
            $iv=substr(hash('sha256',$secret_iv),0,16);
            $output=openssl_encrypt($string,$encrypt_method,$key,0,$iv);
            $output=base64_encode($output);
            return $output
    }

javascript Equialent

function decryptString($string) {
        var Utf8 = CryptoJS.enc.Utf8;
        const $secret_key='secret_key';
        const $secret_iv='secret_iv';
        const key= CryptoJS.SHA256($secret_key).toString(CryptoJS.enc.Hex).substring(0,32);
        let iv= CryptoJS.SHA256($secret_iv).toString(CryptoJS.enc.Hex).substring(0,16);
        const encrypt = CryptoJS.enc.Base64.parse($string).toString(CryptoJS.enc.Utf8);
        const decrypt = CryptoJS.AES.decrypt(encrypt, Utf8.parse(key), { iv: Utf8.parse(iv)}).toString(Utf8);
        return decrypt;
    }

Also Don't use secret key & secret iv in browser side, it may affect security

Muthu Kumar
  • 420
  • 5
  • 7
0

Please use this method It's work for me.. Thanks

Typescript Code (Anuglar 4+) :

encryptUsingAES256() {
let _key = CryptoJS.enc.Utf8.parse(your_token_here);
let _iv = CryptoJS.enc.Utf8.parse(your_token_here);
let encrypted = CryptoJS.AES.encrypt(
  this.request, _key, {
    keySize: 16,
    iv: _iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  });
this.encrypted = encrypted.toString();
console.log(this.encrypted)
}


decryptUsingAES256() {
let _key = CryptoJS.enc.Utf8.parse(your_token_here);
let _iv = CryptoJS.enc.Utf8.parse(your_token_here);

this.decrypted = CryptoJS.AES.decrypt(
  this.encrypted, _key, {
    keySize: 16,
    iv: _iv,
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
  }).toString(CryptoJS.enc.Utf8);
   console.log(this.decrypted) 
}
M Danial
  • 166
  • 1
  • 4