AES шифрование в PHP


PHP не имеет встроенной функции для АЭС (в частности, шифрования AES-128) кодирования/декодирования, так что я должен был реализовать свой собственный, и это то, что я пришел, чтобы (разумеется, взятых из разных источников, в основном, не закодированные мною).

Мой вопрос, это правильно? Не сам код, но то, что они делают. Корректность алгоритма. Я проверил их, и они, видимо, работают. Но там может быть тонкие ошибки, которые я пропустила...


Алгоритм кодирования:

function aes128_encode($data, $mode)
{
        switch ($mode) {
        case "ECB":
        case "CBC":
            if ($mode === "ECB") {
                $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
            } else {
                $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
            }

            $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cipher), MCRYPT_RAND);
            $key = substr(CIPHERKEY, 0, mcrypt_enc_get_key_size($cipher));

            if (mcrypt_generic_init($cipher, $key, $iv) != 1) {
                $cipherData = mcrypt_generic($cipher, $data);

                mcrypt_generic_deinit($cipher);
                mcrypt_module_close($cipher);

                if ($mode === "ECB") {
                    $sanitizedCipherData = trim(base64_encode($cipherData)); 
                } else {
                    $sanitizedCipherData = trim(base64_encode($iv)."_".base64_encode($cipherData));
                }

                return $sanitizedCipherData;
            } else {
                return false;
            }
            break;

        default:
            return false;
            break;
        }
    }

Алгоритм декодирования:

function aes128_decode($data, $mode)
{
    switch ($mode) {
    case "ECB":
        $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
        $key = substr(CIPHERKEY, 0, mcrypt_enc_get_key_size($cipher));

        // Fake iv to call mcrypt_generic_init
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cipher), MCRYPT_RAND);
        $cipherData = base64_decode($data);

        if (mcrypt_generic_init($cipher, $key, $iv) != -1) {
            $originalData = mdecrypt_generic($cipher, $cipherData);
            mcrypt_generic_deinit($cipher);
            mcrypt_module_close($cipher);

            return $originalData;
        } else {
            return false;
        }
        break;

    case "CBC":
        $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        $key = substr(CIPHERKEY, 0, mcrypt_enc_get_key_size($cipher));
        $parts = explode("_", $data);
        $iv = base64_decode($parts[0]); 
        $cipherData = base64_decode($parts[1]);

        if (mcrypt_generic_init($cipher, $key, $iv) != -1) {
            $originalData = mdecrypt_generic($cipher, $cipherData);
            mcrypt_generic_deinit($cipher);
            mcrypt_module_close($cipher);

            return $originalData;
        } else {
            return false;
        }
        break;

    default:
        return false;
        break;
    }
}

Примечание: в $режиме переменной указывает, какой режим работы будет использоваться (ЕЦБ или ПГС). В CIPHERKEY является постоянным с произвольной значения, которые должны быть известны только админ сайта.



10286
3
задан 17 октября 2011 в 06:10 Источник Поделиться
Комментарии
3 ответа

Реализация только AES является очень рискованным, главным образом, потому что очень легко ошибиться. Я настоятельно рекомендую вам использовать phpseclib для этого.

Также не следует использовать режим ECB, если вы не шифрования только 1 блок.

10
ответ дан 17 октября 2011 в 06:10 Источник Поделиться

Как я понимаю, единственная разница между AES и Rijndael является то, что АЭС ограничивается 128-битный размер блока и может использовать только размером ключа 128, 192 и 256 бит. Так что если вы используете Rijndael_128 с одним из этих трех основных длинах, то вы находитесь использует AES.

Если вы должны иметь что-то, что говорит ня, тогда, как Крис Смит сказал, использовать phpseclib.

4
ответ дан 17 октября 2011 в 07:10 Источник Поделиться

PHP может не имеет встроенного шифрования AES библиотеки, но бесплатно никто существовать для ЕЦБ или другой тип вы можете проверить, что открытым исходным кодом проекта. Я настоятельно рекомендую не изобретать велосипед, потому что он может быть подвержен ошибкам.

1
ответ дан 17 октября 2011 в 06:10 Источник Поделиться