R
R
romaprogrammer2016-01-18 10:23:33
PHP
romaprogrammer, 2016-01-18 10:23:33

How to implement data encryption in php?

Here is an example in 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;
    }

Need to reformat to php.
I was able to decrypt with 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';`- random number hash `$iv = '00000000000000000000000000000000'; ric constant.
Now you need to encrypt the password back using a random number and send a written 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'm trying 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 long and in 16-bit form, but it is not sent to the server when it is decrypted.
Here is an example of a function on Oracle that does decryption on 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;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
N
Nikolai Katkov, 2016-01-19
@ZaitsZaits

Try like this
JS:

/**
 * Зашифровать сообщение AES ключом
 * 
 * @param string шифруемое сообщение
 * @param key ключ, 8 символов от 0 до F
 * @return string зашифрованное сообщение
 */
function encrypt (string, key){
  var mykey = CryptoJS.enc.Hex.parse(key+key+key+key);
  var iv  = CryptoJS.enc.Hex.parse('00000000000000000000000000000000');
  string='_crc_'+string+String.fromCharCode(0);
  var len=string.length;
  var ost=len%16;
  for (var i=0;i<ost-1;i++)
      string=string+String.fromCharCode(getRandomInt(65,90));
  var encrypted = CryptoJS.AES.encrypt(
    string, 
    mykey, 
    {
      keySize: 128 / 8, 
      iv: iv, 
      mode: CryptoJS.mode.CBC, 
      padding: CryptoJS.pad.Pkcs7
    }
  );
  var encr=encrypted.ciphertext.toString(CryptoJS.enc.Hex);
  return encr;
}

/**
 * Расшифровать сообщение AES ключом
 * 
 * @param crypted зашифрованные данные
 * @param key ключ, 8 символов от 0 до F
 * @return string расшифрованное сообщение
 */
function decrypt(crypted, key) {
  try {
    var mykey = CryptoJS.enc.Hex.parse(key+key+key+key);
    var iv  = CryptoJS.enc.Hex.parse('00000000000000000000000000000000');
    var ciphertext = CryptoJS.enc.Hex.parse(crypted);
    var encrypted = new Object();
    encrypted.ciphertext = ciphertext;
    var decrypted = CryptoJS.AES.decrypt(
      encrypted, 
      mykey, 
      {
        keySize: 128 / 8, 
        iv: iv, 
        mode: CryptoJS.mode.CBC, 
        padding: CryptoJS.pad.Pkcs7
      }
    );
    var decr=CryptoJS.enc.Utf8.stringify(decrypted);
  
    var decr2 = "";
    var endIndex = 0;
    for (var i = 0; i<decr.length; i++) {
      if (decr.charCodeAt(i)==0) {
        endIndex=i;
        break;
      }
    }
    
    decr2=decr.substr(0, endIndex);
    
    if (decr2.indexOf('_crc_') !== 0) throw new Error(); 
      
    return decr2.substr(5);
      
  } catch (e) {
      throw "Ошибка расшифровки ответа сервера"; 
  }
}

PHP:
function encrypt ($string, $key) {
    
  //проверяем, чтобы длина ключа была 8 символов
  if (mb_strlen($key,'utf-8') !== 8) 
    throw new Exception ("Длина ключа должна быть 8 символов");

  //устанавливаем тип алгоритма
  $keySize      = MCRYPT_RIJNDAEL_128;
  $mode         = MCRYPT_MODE_CBC;

  //формируем полный ключ, полный ключ состоит из повторяющихся четыре раза ключа, итого 32 байта
  $fullkeystring=$key.$key.$key.$key;

  //преобразуем ключ из строки в байтовый массив
  $mykey=pack("H*",strtoupper($fullkeystring));

  //IV используем нулевой
  $iv=pack("H*",'00000000000000000000000000000000');

  //добавляем к сообщению заголовок, по которому потом будем определять, расшифровалось или нет, в конец записываем 0
  $string='_crc_'.$string.chr(0);

  //дополняем строку до границы разным мусором
  $len=strlen($string);
  $ost=$len % 16;
  for ($i=0;$i<$ost-1;$i++) 
    $string=$string.chr(rand(65, 90));

  //шифруем
  $ciphertext = mcrypt_encrypt($keySize, $mykey, $string, $mode, $iv); 

  //преобразуем байтовый массив в строку содержащую шестнадцатеричный код, и возвращаем ее
  return strtoupper(bin2hex($ciphertext));
}

function decrypt ($crypted, $Key) {

  //проверяем, чтобы длина ключа была 8 символов
  if (mb_strlen($Key,'utf-8') !== 8) 
    throw new Exception ("Неверная длина ключа");

  //устанавливаем тип алгоритма
  $keySize      = MCRYPT_RIJNDAEL_128;
  $mode         = MCRYPT_MODE_CBC;

  //формируем полный ключ, полный ключ состоит из повторяющихся четыре раза ключа, итого 32 байта
  $fullkeystring=$Key.$Key.$Key.$Key;

  //преобразуем ключ из строки в байтовый массив
  $mykey=pack("H*",strtoupper($fullkeystring));

  //IV используем нулевой
  $iv=pack("H*",'00000000000000000000000000000000');

  //преобразуем строку к верхнему регистру, а затем из шестнадцатеричного кода преобразуем в массив байтов
  $BinMessage=pack("H*",strtoupper($crypted));

  //дешифруем сообщение
  $decrypt=mcrypt_decrypt($keySize, $mykey, $BinMessage, $mode, $iv); 

  //обрезаем пробелы
  $result = trim($decrypt);

  //проверяем, корректно ли расшифровалось, или нет
  if (strpos($result,'_crc_') !== false && strpos($result,'_crc_') === 0) {

    //убираем лишний мусор содержащейся в конце строки
    if (strpos($result, chr(0))>0)
      $result = substr($result, 0, strpos($result, chr(0)));

    return substr ($result, 5);  //если все нормально, возвращаем строку
  }
  else throw new Exception ("Неверный ключ шифрования");
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question