хранение хешированных паролей - base64, или шестнадцатеричная строка или что-то еще?

Я решил проблему следующим образом:

(1) Перейдите к веткам, в которых есть файлы миграции, и откатите их назад. Это не тривиально, когда у вас много ветвей, которые приведут к множеству конфликтов, если вы попытаетесь объединить их. Поэтому я использую эти команды, чтобы узнать, к каким ветвям принадлежит каждая сиротская миграция.

Итак, мне нужно найти коммит последнего изменения миграции.

git log --all --reverse --stat | grep <LASTEST_ORPHAN_MIGRATION_ID> -C 10

Я беру хеш коммита и определяю, к какой ветви он принадлежит, например:

git branch --contains <COMMIT_HASH>

Затем я могу вернуться к этой ветке, выполнить откат и повторить этот процесс для всех отсутствующих файлов. .

(2) Запустите миграцию: извлеките ветку, над которой вы, наконец, хотите поработать, и запустите миграции, и вы должны быть в порядке.

Устранение неполадок

Я также работал в некоторых случаях, когда осиротевшие миграции были на удаленных ветвях.

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

Другой альтернативой является прямое удаление отсутствующих файлов из базы данных:

delete from schema_migrations where version='<MIGRATION_ID>';
16
задан joedotnot 4 June 2009 в 13:49
поделиться

9 ответов

Даже если ваше решение не является Fort-Knox, вам следует проявить усердие и применить соление. Поскольку многие люди повторно используют свои пароли в других местах, а взлом нанесет дополнительный ущерб за пределами вашей организации, если злоумышленники решат использовать базу данных взломанных паролей для других целей.

Использование соли делает словарные атаки более дорогими. Решив, какой размер соли использовать, вы сможете точно настроить свои шансы. Вот цитата из книги Брюса Шнайера «Прикладная криптография»:

«Соль - не панацея; увеличение количества солевых битов не решит все. Соль защищает только от общих словарных атак на файл паролей, а не от согласованных атак. с одним паролем. Он защищает людей, имеющих один и тот же пароль на нескольких машинах, но не улучшает плохо выбранные пароли »

Вот пример на C #. Это не так уж сложно. И вы можете выбрать, какой размер соли и хеш-функцию использовать. Отказ от ответственности: используйте что-то вроде bcrypt , если вы действительно заботитесь о целостности пароля.


using System;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

public class PassHash {
    private static readonly RandomNumberGenerator rng = RandomNumberGenerator.Create();
    public static readonly int DefaultSaltSize = 8; // 64-bit salt
    public readonly byte[] Salt;
    public readonly byte[] Passhash;

    internal PassHash(byte[] salt, byte[] passhash) {
        Salt = salt;
        Passhash = passhash;
    }

    public override String ToString() {
        return String.Format("{{'salt': '{0}', 'passhash': '{1}'}}",
                             Convert.ToBase64String(Salt),
                             Convert.ToBase64String(Passhash));
    }

    public static PassHash Encode<HA>(String password) where HA : HashAlgorithm {
        return Encode<HA>(password, DefaultSaltSize);
    }

    public static PassHash Encode<HA>(String password, int saltSize) where HA : HashAlgorithm {
        return Encode<HA>(password, GenerateSalt(saltSize));
    }

    private static PassHash Encode<HA>(string password, byte[] salt) where HA : HashAlgorithm {
        BindingFlags publicStatic = BindingFlags.Public | BindingFlags.Static;
        MethodInfo hasher_factory = typeof (HA).GetMethod("Create", publicStatic, Type.DefaultBinder, Type.EmptyTypes, null);
        using (HashAlgorithm hasher = (HashAlgorithm) hasher_factory.Invoke(null, null))
        {
            using (MemoryStream hashInput = new MemoryStream())
            {
                hashInput.Write(salt, 0, salt.Length);
                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                hashInput.Write(passwordBytes, 0, passwordBytes.Length);
                hashInput.Seek(0, SeekOrigin.Begin);
                byte[] passhash = hasher.ComputeHash(hashInput);
                return new PassHash(salt, passhash);
            }
        }
    }

    private static byte[] GenerateSalt(int saltSize) {
        // This generates salt.
        // Rephrasing Schneier:
        // "salt" is a random string of bytes that is
        // combined with password bytes before being
        // operated by the one-way function.
        byte[] salt = new byte[saltSize];
        rng.GetBytes(salt);
        return salt;
    }

    public static bool Verify<HA>(string password, byte[] salt, byte[] passhash) where HA : HashAlgorithm {
        // OMG: I don't know how to compare byte arrays in C#.
        return Encode<HA>(password, salt).ToString() == new PassHash(salt, passhash).ToString();
    }
}

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

Новый пользователь отправляет свои учетные данные.

PassHash ph = PassHash.Encode (new_user_password);

Store ph.Salt & ph.Passhash где-то ... Позже, когда пользователь снова войдет в систему, вы увидите запись пользователя с солью и паролем, а затем вы делаете это:

PassHash.Verify (user_login_password, user_rec.salt, user_rec.passhash)

}

12
ответ дан 30 November 2019 в 16:58
поделиться

Между прочим, при таком большом количестве алгоритмов хеширования я случайно выбрал SHA384, но есть ли тот, который «лучше» или подходит для задачи?

В общем, я бы избегал MD5 или SHA-0 или SHA-1. Но на данный момент SHA-384 должно быть достаточно для ваших нужд. См. этот вопрос для обсуждения некоторых алгоритмов.

4
ответ дан 30 November 2019 в 16:58
поделиться

Base64 действительно короче шестнадцатеричного, с небольшим недостатком: вам нужно быть осторожным, если он когда-либо попадет в URL (из-за задействованных символов). В основном это зависит от того, где вы его используете. Обычно шестнадцатеричный код имеет то преимущество, что его легче «читать» невооруженным глазом, но поскольку это будут по существу бессмысленные данные, это не имеет отношения к хешу. (При необходимости вы всегда можете использовать онлайн-декодирование base64.)

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

8
ответ дан 30 November 2019 в 16:58
поделиться

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

И если вы не Делая это, убедитесь, что вы солили свои пароли перед их хешированием, чтобы защититься от более распространенных хакерских атак (определение похожих паролей, радужные таблицы и т. д.). Прочтите эту статью для получения дополнительной информации.

Для записи, мне нравится Base64, так как .NET имеет встроенные процедуры для преобразования в / из него.

4
ответ дан 30 November 2019 в 16:58
поделиться

Интересное примечание, которое я видел раньше: если у вас есть массив байтов и вы его кодируете base64, некоторые из результирующих символов могут вызвать проблемы в URL-адресах - однако, если вы кодируете base64 во второй раз эти оскорбительные символы, как правило, удаляются, а строку base64 можно использовать в URL-адресах. Вы можете сравнить, используя строку с двойным кодированием.

Для алгоритмов хеширования sha384, вероятно, является достаточным алгоритмом, но убедитесь, что вы добавили свой хэш!

4
ответ дан 30 November 2019 в 16:58
поделиться

Вы также можете преобразовать его в простые байты. Таким образом, 128-битное хеш-значение MD5 приведет к длине строки 128 бит / 8 бит / байт = 16 байт.

3
ответ дан 30 November 2019 в 16:58
поделиться

Я бы использовал Base64 .... о, и не забывайте солить свой хеш, если это пароль, который вы хешируете :) И все, что меньше SHA384, представляет собой угрозу безопасности, если мы говорим о пароле, потому что так легко получить качественные радужные таблицы для SHA1 и других распространенных алгоритмов хеширования.

0
ответ дан 30 November 2019 в 16:58
поделиться

Ответ зависит от контекста и ограничений, которые у вас могут быть. Base64 будет более компактным, но его создание будет немного более затратным по сравнению с шестнадцатеричным кодированием.

Вы должны добавить соли к вашим хешированным данным. Это случайное значение, которое ставится перед хешируемым паролем. Затем сохраните значение соли с хешированным значением, чтобы вы могли восстановить хеш-значение.

Роль этой соли - предотвратить построение словаря, отображающего общие пароли в хешированные значения. Если кто-то может получить копию вашего файла с хешированными паролями, он может использовать этот словарь, чтобы найти пароль в открытом виде. С 16-битной солью у вас есть 65536 различных значений хэша для одного и того же пароля в открытом виде. Словарная атака становится менее эффективной. Лучше выбрать 64-битную соль, потому что это не добавит много усилий для хеширования и проверки паролей.

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

Что касается алгоритмов использования SHA1, это очень хорошо, а SHA256 будет поясом и ремнями. MD5 намного дешевле в вычислении и удовлетворяет большинству вариантов использования. Учтите это, если ваши ресурсы обработки и хранения могут быть ограничивающим фактором.

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

Что касается алгоритмов использования SHA1, это очень хорошо, а SHA256 будет поясом и ремнями. MD5 намного дешевле в вычислении и удовлетворяет большинству вариантов использования. Учтите это, если ваши ресурсы обработки и хранения могут быть ограничивающим фактором.

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

Что касается алгоритмов использования SHA1, это очень хорошо, а SHA256 будет поясом и ремнями. MD5 намного дешевле в вычислении и удовлетворяет большинству вариантов использования. Учтите это, если ваши ресурсы обработки и хранения могут быть ограничивающим фактором.

0
ответ дан 30 November 2019 в 16:58
поделиться

Что касается паролей, я считаю, что любой из них отлично подходит. SHA 512 создаст более высокий ключ, уменьшая вероятность «коллизии», зная, что разные пароли могут иметь один и тот же хэш, но вероятность очень мала.

0
ответ дан 30 November 2019 в 16:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: