Шифрование AES-256 в PHP


Мне нужна функция PHP, AES256_encode($dataToEcrypt) для шифрования $data в AES-256, а другая AES256_decode($encryptedData) делает обратное. Кто-нибудь знает, какой код должен быть у этих функций?

Author: user2864740, 2011-07-21

4 answers

Посмотрите на модуль mcrypt

Пример AES-Rijndael взят из здесь

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
# show key size use either 16, 24 or 32 byte keys for AES-128, 192
# and 256 respectively
$key_size =  strlen($key);
echo "Key size: " . $key_size . "\n";
$text = "Meet me at 11 o'clock behind the monument.";
echo strlen($text) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_CBC, $iv);
echo strlen($crypttext) . "\n";

Это функция расшифровки

 14
Author: Fabio, 2013-06-22 15:59:41

MCRYPT_RIJNDAEL_256 не эквивалентно AES_256.

Способ расшифровать RIJNDAEL из AES - использовать MCRYPT_RIJNDAEL_128 и добавить строку для шифрования перед шифрованием

AES-256 имеет размер блока=128 бит и размер ключа=256 бит Rijndael-256 имеет размер блока=256 бит и размер ключа=256 бит

Только 128-битные AES/Rijndael идентичны. Rijndael-192 и Rijndael-256 не идентичны AES-192 и AES-256 (размеры блоков и количество раундов различаются).

 13
Author: Behzad-Ravanbakhsh, 2013-06-22 10:41:33

Мне нужна функция PHP, AES256_encode($dataToEcrypt) для шифрования $data в AES-256, а другая AES256_decode($encryptedData) делает обратное. Кто-нибудь знает, какой код должен быть у этих функций?

Существует разница между шифрованием и кодированием.

Вам действительно нужен AES-256? Безопасность AES-256 по сравнению с AES-128 не так уж важна; у вас больше шансов облажаться на уровне протокола, чем быть взломанным, потому что вы использовали 128-битный блочный шифр вместо 256-битный блочный шифр.

Важно - Используйте Библиотеку

A flowchart for PHP users

Быстрая и грязная реализация AES-256

Если вы заинтересованы в создании своего собственного не ради его развертывания в производстве, а скорее ради вашего собственного образования, я включил образец AES256

/**
 * This is a quick and dirty proof of concept for StackOverflow.
 * 
 * @ref http://stackoverflow.com/q/6770370/2224584
 * 
 * Do not use this in production.
 */
abstract class ExperimentalAES256DoNotActuallyUse
{
    /**
     * Encrypt with AES-256-CTR + HMAC-SHA-512
     * 
     * @param string $plaintext Your message
     * @param string $encryptionKey Key for encryption
     * @param string $macKey Key for calculating the MAC
     * @return string
     */
    public static function encrypt($plaintext, $encryptionKey, $macKey)
    {
        $nonce = random_bytes(16);
        $ciphertext = openssl_encrypt(
            $plaintext,
            'aes-256-ctr',
            $encryptionKey,
            OPENSSL_RAW_DATA,
            $nonce
        );
        $mac = hash_hmac('sha512', $nonce.$ciphertext, $macKey, true);
        return base64_encode($mac.$nonce.$ciphertext);
    }

    /**
     * Verify HMAC-SHA-512 then decrypt AES-256-CTR
     * 
     * @param string $message Encrypted message
     * @param string $encryptionKey Key for encryption
     * @param string $macKey Key for calculating the MAC
     */
    public static function decrypt($message, $encryptionKey, $macKey)
    {
        $decoded = base64_decode($ciphertext);
        $mac = mb_substr($message, 0, 64, '8bit');
        $nonce = mb_substr($message, 64, 16, '8bit');
        $ciphertext = mb_substr($message, 80, null, '8bit');

        $calc = hash_hmac('sha512', $nonce.$ciphertext, $macKey, true);
        if (!hash_equals($calc, $mac)) {
            throw new Exception('Invalid MAC');
        }
        return openssl_decrypt(
            $ciphertext,
            'aes-256-ctr',
            $encryptionKey,
            OPENSSL_RAW_DATA,
            $nonce
        );
    }
}

Использование

Во-первых, сгенерируйте два ключа (да, два из них) и каким-то образом сохраните их.

$eKey = random_bytes(32);
$aKey = random_bytes(32);

Затем для шифрования/дешифрования сообщений:

$plaintext = 'This is just a test message.';
$encrypted = ExperimentalAES256DoNotActuallyUse::encrypt($plaintext, $eKey, $aKey);
$decrypted = ExperimentalAES256DoNotActuallyUse::decrypt($encrypted, $eKey, $aKey);

Если у вас нет random_bytes(), получите random_compat.

 12
Author: Scott Arciszewski, 2016-02-18 22:17:56
$key = '324325923495kdfgiert734t'; // key used for decryption in jasper code
$text = 'string_to_be_encrypted';
$encrypted = fnEncrypt($text, $key);




function fnEncrypt( $plaintext, $key )
{
$plaintext = pkcs5_pad($plaintext, 16);

return bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, hex2bin($key), $plaintext, MCRYPT_MODE_ECB));

}


function pkcs5_pad ($text, $blocksize)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}



function hex2bin($hexdata) 
{
$bindata = "";

    for ($i = 0; $i < strlen($hexdata); $i += 2) 
    {
      $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
    }

return $bindata;
}
 -2
Author: sourav, 2014-05-27 08:07:31