За последние 24 часа нас посетили 22614 программистов и 1017 роботов. Сейчас ищут 688 программистов ...

Crypto node\php

Тема в разделе "Решения, алгоритмы", создана пользователем admyx, 8 фев 2017.

  1. admyx

    admyx Активный пользователь

    С нами с:
    14 мар 2008
    Сообщения:
    2.159
    Симпатии:
    1
    Я очень давно не писал статьи по php, со времен ... да уж не помню.
    Но чем-то хочется поделиться, тем не менее.
    Сразу скажу - исходные тексты писал не я, но тестировал на своей машине.

    Речь пойдет о шифровании 128 бит из ноды в пхп и наоборот

    PHP:
    1. /**
    2. * Encrypt and decrypt data from server to server.
    3. *
    4. * @package
    5. * @subpackage app\components\crypt
    6. * @see https://gist.github.com/rojan/9545706
    7. * @author rojan
    8. */
    9. class Crypto implements CryptInterface{
    10.     /**
    11.      * Encryption key
    12.      *
    13.      * @var string
    14.      */
    15.     private $encryptKey;
    16.  
    17.     /**
    18.      * Initialization vector
    19.      *
    20.      * @var string
    21.      */
    22.     private $iv;
    23.  
    24.     /**
    25.      * Blocksize
    26.      *
    27.      * @var int
    28.      */
    29.     private $blocksize = 16;
    30.  
    31.     /**
    32.      * Setting up encrypt key and initialization vector.
    33.      *
    34.      * @param string $encryptKey  Ecrypt key
    35.      * @param string $iv          Initialization vector
    36.      * @return void
    37.      */
    38.     public function setCredentials(string $encryptKey, string $iv){
    39.         $this->encryptKey = $encryptKey;
    40.         $this->iv = $iv;
    41.     }
    42.  
    43.     /**
    44.      * Returns decrypted data.
    45.      *
    46.      * @param string $data  Encrypted data
    47.      * @return string
    48.      */
    49.     public function decrypt(string $data) : string{
    50.         return $this->unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
    51.             $this->encryptKey,
    52.             hex2bin($data),
    53.             MCRYPT_MODE_CBC, $this->iv), $this->blocksize);
    54.     }
    55.  
    56.     /**
    57.      * Returns encrypted data.
    58.      *
    59.      * @param string $data  Plain data
    60.      * @return string
    61.      */
    62.     public function encrypt(string $data) : string{
    63.         //don't use default php padding which is '\0'
    64.         $pad = $this->blocksize - (strlen($data) % $this->blocksize);
    65.         $data = $data . str_repeat(chr($pad), $pad);
    66.         return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
    67.             $this->encryptKey,
    68.             $data, MCRYPT_MODE_CBC, $this->iv));
    69.     }
    70.  
    71.     /**
    72.      * Unpad the data.
    73.      *
    74.      * @param string $str        Data string
    75.      * @param int    $blocksize  Size of the block
    76.      * @return string
    77.      */
    78.     private function unpad(string $str, int $blocksize) : string{
    79.         $len = mb_strlen($str);
    80.         $pad = ord( $str[$len - 1] );
    81.         if ($pad && $pad < $blocksize) {
    82.             $pm = preg_match('/' . chr($pad) . '{' . $pad . '}$/', $str);
    83.             if( $pm ) {
    84.                 return mb_substr($str, 0, $len - $pad);
    85.             }
    86.         }
    87.         return $str;
    88.     }
    89.  
    90. }
    это, разумеется, мой класс для шифрования, основанный на решении уважаемого rojan. - CryptInterface можно удалить в любое время.

    в ответе в node, к сожалению, не могу выложить свой код из ноды, могу только приложить решение от rojan.

    Код (Javascript):
    1. var crypto = require('crypto');
    2. var key = 'MySecretKey12345';
    3. var iv = '1234567890123456';
    4. var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    5. var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
    6.  
    7. var text = 'plain text';
    8. var encrypted = cipher.update(text, 'utf8', 'binary');
    9. encrypted += cipher.final('binary');
    10. hexVal = new Buffer(encrypted, 'binary');
    11. newEncrypted = hexVal.toString('hex');
    12. console.log('Encrypted: ', newEncrypted);
    13.  
    14. var decrypted = decipher.update(newEncrypted, 'hex', 'binary');
    15. decrypted += decipher.final('binary');
    16.  
    17. console.log('Decrypted: ', decrypted);
    Тут у меня возникла проблема.
    Нода отдает шифрование с несколькими лишними байтами справа.

    Лечить пришлось так (лечение отвратительное, сразу говорю. но - лично у меня других данных не предполагается, вы можете всегда изменить паттерн под свои нужды)

    PHP:
    1. public static function normalizeJSON(string $string) : string{
    2.         return preg_replace('/[^a-zA-Z0-9\-\_\{\}:\",\[\]\(\)\\/\.\@&; ]/ui', '', $string);
    3.     }
    с 256 бит шифрованием отдельная головная боль, если кому-то будет интересно, выложу позже, с описанием либ под linux.
     
    #1 admyx, 8 фев 2017
    Последнее редактирование модератором: 8 фев 2017