Случайная строка + шифровать/дешифровать


Есть какие-то изъяны в безопасности в том, что я планирую сделать?

Мне нужно хранить в своей БД:

  1. случайную строку в качестве соли для шифрования пароля
  2. зашифрованный пароль, который использовали соль в #1

Вот PHP-код, мне нужно выполнить указанные выше задачи:

<?php
    function decrypt($string, $encryption_key = '')
    {
        $initialization_vector = get_initialization_vector();

        // Convert hexadecimal data into binary representation
        $string = hex2bin($string);

        // See: http://php.net/manual/en/mcrypt.ciphers.php
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_ECB, $initialization_vector));
    }

    function encrypt($string, $encryption_key = '')
    {
        $initialization_vector = get_initialization_vector();

        // See: http://php.net/manual/en/mcrypt.ciphers.php
        $string = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $encryption_key, $string, MCRYPT_MODE_ECB, $initialization_vector);

        // Convert binary data into hexadecimal representation
        $string = bin2hex($string);

        return $string;
    }


    function get_initialization_vector()
    {
        // See: http://php.net/manual/en/mcrypt.ciphers.php
        // MCRYPT_BLOWFISH selected as it appears to be one of the "universally"
        // supported ciphers supported by the mcrypt extension
        $initialization_vector_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

        // See: http://php.net/manual/en/function.mcrypt-create-iv.php
        // The source can be MCRYPT_RAND (system random number generator), MCRYPT_DEV_RANDOM
        // (read data from /dev/random) and MCRYPT_DEV_URANDOM (read data from /dev/urandom).
        // Prior to 5.3.0, MCRYPT_RAND was the only one supported on Windows.
        $initialization_vector = mcrypt_create_iv($initialization_vector_size, MCRYPT_RAND);

        return $initialization_vector;
    }

    function get_random_string($character_set = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', $minimum_length = 8, $maximum_length = 12)
    {
        if ($minimum_length > $maximum_length)
        {
            $length = mt_rand($maximum_length, $minimum_length);
        }
        else
        {
            $length = mt_rand($minimum_length, $maximum_length);
        }

        $random_string = '';
        for ($i = 0; $i < $length; $i++)
        {
            $random_string .= $character_set[(mt_rand(0, (strlen($character_set) - 1)))];
        }

        return $random_string;
    }

    function hex2bin($hexadecimal_data)
    {
        $binary_representation = '';

        for ($i = 0; $i < strlen($hexadecimal_data); $i += 2)
        {
            $binary_representation .= chr(hexdec($hexadecimal_data{$i} . $hexadecimal_data{($i + 1)}));
        }

        return $binary_representation;
    }


2541
3
задан 20 ноября 2011 в 05:11 Источник Поделиться
Комментарии
2 ответа

Почему шифрование не подходит под цели хранения паролей

Криптографического хеширования и шифрования двух различных целей. Хеширование не является обратимым, учитывая хэш, вы не можете определить, что сделал он, кроме тестирования, чтобы увидеть, если источник входного сигнала соответствует хеша. При использовании паролей, это будет только вопрос проверки: "этот пароль (смешанное с солью) матч?" С паролями, цель состоит в том, чтобы предотвратить кого-то с полным доступом к базе данных восстановления паролей.

Шифрование паролей ручки этой цели плохо. Чтобы проверить пароль, надо иметь ключ шифрования. Это означает, что можно определить пароль источником глядя на зашифрованную версию пароля. В случае компромисса, имея эти зашифрованные поля и ключа приведет к раскрытию всех паролей, независимо от того, насколько сильными они были.

Хорошие Ресурсы

https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords

Правила крипто

Вы найдете его здесь: не свернуть свой собственный слух. Проблема в том, что поле слишком изменилась для "здравого смысла", чтобы действительно быть что-то, что работает на нашу пользу. Шифрование и проблемы пароль развивались достаточно быстро в масштабах человеческой жизни, время. Там не все такие, что много различных идей существует о том, как решить эти проблемы и многие из них были опровергнуты.

Если ты не в теме, Правильный подход заключается в исследовании проблемы, которую вы пытаетесь решить, а не способ вы пытаетесь решить его.

5
ответ дан 20 ноября 2011 в 07:11 Источник Поделиться

Чтобы обобщить то, что вы делаете здесь:

Вы использовать AES в ECB-режим, с каким-то неизвестным ключом, чтобы зашифровать пароль.

Можно также попробовать использовать случайный вектор инициализации в качестве соли для шифрования.

Я вижу такие проблемы:


  • Как правило, вы не хотите, чтобы зашифровать пароль, а хэш вместо этого. Посмотрите на недавний блог статьи об этой теме, Что ссылки на соответствующие вопросы.

    Если этот пароль используется только для проверки логина, нет необходимости
    хранить его в зашифрованном виде, а не хэш. Только хранить сам пароль
    если вам это нужно для входа куда-то еще. (Но это может открыть другой
    может глисты, так что подумайте об использовании чего-то еще здесь.)


  • ЕЦБ-режиме, который вы используете, не имеет вектора инициализации. Так что ваш код будет на самом деле генерировать нулевой длины случайную строку (или больше одного, который не будет использоваться).

    Шифрование дважды один и тот же пароль приведет к тому же шифротекст оба раза. Никогда не используйте ЕЦБ-режиме (если вы не уверены, что это правильная вещь, чтобы использовать по какой-то причине), использовать CBC-режимом или CTR вместо. После инициализации поколения вектор, на самом деле будет что-то делать (смотри следующий пункт).


  • Вы сгенерировать случайный вектор инициализации на расшифровку. Это не
    тебя сейчас ударил, так как он фактически не используется (см. предыдущий пункт), но если вы
    используя его, вы действительно должны хранить его вместе с зашифрованным
    данные и получить его до расшифровки, в противном случае первый блок (16 байт)
    из расшифрованного текста (для ПГС) будет фигня.

И не относящиеся к безопасности Примечание:


  • Вам не нужно шестнадцатеричными, если вы определите вашу базу данных
    столбец тип Binary (двоичный или типа varbinary) вместо текстового типа.
    Это будет безопасное место (и чуть-чуть времени обработки).

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