Here is an example on JS:

function decryptRandomNumber (pwdHash, encryptedRandomNumber) { var key = CryptoJS.enc.Utf8.parse(pwdHash); var encrypted = CryptoJS.enc.Hex.parse(encryptedRandomNumber.toUpperCase()); var result = CryptoJS.AES.decrypt({ ciphertext: encrypted }, key , { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); return result; } function encryptPwdHash (pwdHash, randomNumber) { var randomNumberMd5 = CryptoJS.MD5(randomNumber).toString().toUpperCase(); var key = CryptoJS.enc.Utf8.parse(randomNumberMd5); var result = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(pwdHash), key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).ciphertext; return result; } // пример на js - шифрование var password = '123456'; var pwdHash = CryptoJS.MD5(password).toString().toUpperCase(); var encriptResult = encryptPwdHash (pwdHash, '3456'); // 

Screenshot of the result
gdfgdfgdfg
if you bring in a string then f46492dc512a6df5cd7c6b9ee50e7cc44fb2337c1605726518d353ce800d5cc05d4d5540dd7674850079e785ab5f3b77

Need to rewrite to PHP.

Decryption could be done here by this function.

  function aes128_cbc_decrypt($key, $data, $iv) { $data = pack("H*", $data); $iv = pack("H*", $iv); $dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); return $dec; } 

Input parameters -> $key = strtoupper(md5($password)); password hash $data = '54BAA6158E81E1069EA2AB1C4F9D1F29'; - hash of random number $iv = '00000000000000000000000000000000'; - a vector in the form of a 16 - tic constant.

Now you need to encrypt the password back using a random number and send. Wrote a function that does this:

 function aes128_cbc_encript($key, $data, $iv) { $key = pack("H*", strtoupper(md5($key))); //var_dump($data); //$data = pack("H*", $data); $iv = pack("H*", $iv); //$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); $enc = openssl_encrypt($data, 'AES-128-CBC', $key, true, $iv); return bin2hex($enc); } 

I try to run

 $decript = '34345'; // расшифрованное рандомное число $pswdHash = strtoupper(md5($password)); $encript = aes128_cbc_encript($decript, $pswdHash, '00000000000000000000000000000000'); 

At the output I get something - 72fc1b49db86787b749c3323421496af00933eb79a9b7d845a51f5ea3fefdf750800554f5fdf0c7d3d765fe7f6653da3

Such a cipher should be in length and in a 16 - bit form, but it is not correct and it will not be decrypted when sent to the server.

Here is an example of a function on Oracle that decrypts the server

  Fc_Decrypt_Password_Hash(In_Encrypted_Password_Hash In Varchar2, In_Random_Number_Md5 In Varchar2) Return Varchar2 Is Raw_Random_Number_Md5 Raw(2000); Raw_Result Raw(2000); Result Varchar2(2000); Begin Raw_Random_Number_Md5 := Utl_I18n.String_To_Raw(Upper(In_Random_Number_Md5), 'AL32UTF8'); Raw_Result := Dbms_Crypto.Decrypt(Typ => Dbms_Crypto.Aes_Cbc_Pkcs5, Src => Upper(In_Encrypted_Password_Hash), Key => Raw_Random_Number_Md5); Result := Utl_I18n.Raw_To_Char(Raw_Result, 'AL32UTF8'); Return(Result); End; 
  • Why do you encrypt it at all? Wouldn't it be easier to establish a secure channel to the server if everything is still decrypted there? - etki
  • @Etki Well, there is such a task, encrypted keys are used to communicate with the server - modelfak

3 answers 3

First, if you really want to protect your messaging, use ready-made solutions.

The openssl_encrypt function openssl_encrypt not use the entire $key , but only the first 16 bytes, the rest are discarded (for AES-128). Although this is only a practical experience, perhaps this is not true for all versions. As $key , you use the md5 hash in hex format, and this is 32 bytes. CryptoJS , uses the entire key (or at least more than 16 bytes).

Expect that the results of encryption match, do not have to.

The mcrypt_encrypt function mcrypt_encrypt not know Pkcs7 . It always aligns the block with zeros (and it is not safe). Although in your case alignment is not required (the length of the source text is always divided by 16), according to the above standard, you still need to add alignment, it will be 16 bytes 0x10 .

Example of working code (almost repeats your example on js):

 function encrypt(){ $data=strtoupper(md5('123456')); $data.=str_repeat(chr(16), 16);// добавляем выравнивание $key=strtoupper(md5('3456')); $iv=hex2bin(str_repeat('00', 16)); $enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); return bin2hex($enc); } var_dump(encrypt()); // -> string(96) "f46492dc512a6df5cd7c6b9ee50e7cc44fb2337c1605726518d353ce800d5cc05d4d5540dd7674850079e785ab5f3b77" 

    Since you have a task to simply implement encrypted data exchange between the client and the server, I suggest just a ready implementation.

    PHP library:

     /** * Decrypt data from a CryptoJS json encoding string * * @param mixed $passphrase * @param mixed $jsonString * @return mixed */ function cryptoJsAesDecrypt($passphrase, $jsonString){ $jsondata = json_decode($jsonString, true); $salt = hex2bin($jsondata["s"]); $ct = base64_decode($jsondata["ct"]); $iv = hex2bin($jsondata["iv"]); $concatedPassphrase = $passphrase.$salt; $md5 = array(); $md5[0] = md5($concatedPassphrase, true); $result = $md5[0]; for ($i = 1; $i < 3; $i++) { $md5[$i] = md5($md5[$i - 1].$concatedPassphrase, true); $result .= $md5[$i]; } $key = substr($result, 0, 32); $data = openssl_decrypt($ct, 'aes-256-cbc', $key, true, $iv); return json_decode($data, true); } /** * Encrypt value to a cryptojs compatiable json encoding string * * @param mixed $passphrase * @param mixed $value * @return string */ function cryptoJsAesEncrypt($passphrase, $value){ $salt = openssl_random_pseudo_bytes(8); $salted = ''; $dx = ''; while (strlen($salted) < 48) { $dx = md5($dx.$passphrase.$salt, true); $salted .= $dx; } $key = substr($salted, 0, 32); $iv = substr($salted, 32,16); $encrypted_data = openssl_encrypt(json_encode($value), 'aes-256-cbc', $key, true, $iv); $data = array("ct" => base64_encode($encrypted_data), "iv" => bin2hex($iv), "s" => bin2hex($salt)); return json_encode($data); } 

    Javascript library:

     var CryptoJSAesJson = { stringify: function (cipherParams) { var j = {ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)}; if (cipherParams.iv) j.iv = cipherParams.iv.toString(); if (cipherParams.salt) js = cipherParams.salt.toString(); return JSON.stringify(j); }, parse: function (jsonStr) { var j = JSON.parse(jsonStr); var cipherParams = CryptoJS.lib.CipherParams.create({ciphertext: CryptoJS.enc.Base64.parse(j.ct)}); if (j.iv) cipherParams.iv = CryptoJS.enc.Hex.parse(j.iv) if (js) cipherParams.salt = CryptoJS.enc.Hex.parse(js) return cipherParams; } } 

    Javascript example:

     var encrypted = CryptoJS.AES.encrypt(JSON.stringify("value to encrypt"), "my passphrase", {format: CryptoJSAesJson}).toString(); var decrypted = JSON.parse(CryptoJS.AES.decrypt(encrypted, "my passphrase", {format: CryptoJSAesJson}).toString(CryptoJS.enc.Utf8)); 

    PHP example

     $encrypted = cryptoJsAesEncrypt("my passphrase", "value to encrypt"); $decrypted = cryptoJsAesDecrypt("my passphrase", $encrypted); 

    Taken here

    • Thank you, but this option does not work for my server, I have to adapt to a js script that works and data encryption does not work in php, it cannot decrypt what I am sending to it - modelfak
    • @modelfak but what's stopping you from rewriting the script? - Mstislav Pavlov
    • @modelfak Do you understand that there are quite specific encryption algorithms that are not written in your script? - etki
    • @Etki Yes, I understand, this is aes-128, I can not encrypt data by analogy with cryptoJs and I do not understand why - modelfak
    • @modelfak in my version of aes-256. What is the problem to use this working example. If you need exactly aes-128, then it will be enough to make a few edits. - Mstislav Pavlov

    I rewrote everything completely, if this is it, then I will comment after your confirmation.

     <? # ваша функция дешифрования function aes128_cbc_decrypt($key, $data, $iv) { $data = pack("H*", $data); $iv = pack("H*", $iv); $dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); return $dec; } # расшифровываю ваши данные вашей функцией echo aes128_cbc_decrypt(strtoupper(md5('123456')), '54BAA6158E81E1069EA2AB1C4F9D1F29', '00000000000000000000000000000000') . '<br><br>'; # вы зашифровали: 1152 # моя функция для шифрования в режиме CBC function dataEncrypt($plaintext, $key, $iv) { $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, pack('H*', $iv)); $ciphertext = strtoupper(bin2hex($ciphertext)); return $ciphertext; } # шифрую то, что вы шифровали ранне (число 1152) своей функцией echo dataEncrypt('1152', strtoupper(md5('123456')), '00000000000000000000000000000000') . '<br><br>'; # результат: C3364787440D1A610FB3B99C8C6D483C # расшифровываю результат работы своей функции: C3364787440D1A610FB3B99C8C6D483C с помощью вашей функцией aes128_cbc_decrypt echo aes128_cbc_decrypt(strtoupper(md5('123456')), 'C3364787440D1A610FB3B99C8C6D483C', '00000000000000000000000000000000') . '<br><br>'; # я зашифровал: 1152 
    • Thanks, but does not fit, from the script it haws without problems, with PCP it does not want (( - modelfak
    • @modelfak, give an example of the data that you pass to the JS functions of encryptPwdHash and the result of the ciphertext. - Plush
    • Added result and incoming edits to question - modelfak