Ответ 1
Хорошо, поэтому я написал его.
Использование:
hash: string;
hash := TBCrypt.HashPassword('mypassword01');
возвращает что-то вроде:
$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
Полезная вещь в этом хэш-стиле (OpenBSD) стиля:
- что он идентифицирует алгоритм (
2a
= bcrypt) - соль автоматически создается для вас и отправляется с хешем (
Ro0CUfOqk6cXEKf3dyaM7O
) - параметр коэффициента стоимости также переносится с помощью хэша (
10
).
Чтобы проверить правильность пароля:
isValidPassword: Boolean;
isValidPassword := TBCrypt.CheckPassword('mypassword1', hash);
BCrypt использует коэффициент стоимость, который определяет, сколько итераций будет выполняться при настройке ключа. Чем выше стоимость, тем дороже вычислять хэш. Константа BCRYPT_COST
содержит стоимость по умолчанию:
const
BCRYPT_COST = 10; //cost determintes the number of rounds. 10 = 2^10 rounds (1024)
В этом случае стоимость 10
означает, что ключ будет расширен и солен 2 10
= 1024 раунда. Это часто используемый фактор затрат на данный момент времени (начало 21 года st).
Также интересно отметить, что, без какой-либо известной причины, хэшированные пароли OpenBSD преобразуются в вариант Base-64, который отличается от Base64, используемого всеми остальными на планете. Таким образом, TBCrypt
содержит специальный кодировщик и декодер base-64.
Также полезно отметить, что версия алгоритма хеша 2a
используется для обозначения:
- Bcrypt
- включить терминатор нулевого терминатора в хешированных данных
- Строки unicode кодируются в кодировке UTF-8
Поэтому функции HashPassword
и CheckPassword
принимают WideString
(aka UnicodeString
) и внутренне преобразуют их в UTF-8. Если вы используете это в версии Delphi, где UnicodeString
является зарезервированным словом, просто определите:
type
UnicodeString = WideString;
i, как знает Дэвид Хеффернан, не владеют Delphi XE 2. Я добавил псевдоним UnicodeString
, но не включил compilers.inc
и определил прочь UnicodeString
(так как я не знаю имя определения, и я не могу его проверить). Что вы хотите от бесплатного кода?
Код состоит из двух блоков:
- Bcrypt.pas (который я написал со встроенными тестами DUnit)
- Blowfish.pas (который написал Dave Barton, который я адаптировал, расширил, исправил некоторые ошибки и добавил тесты DUnit).
Где на межтрубках я могу поставить код, где он может жить бесконечно?
Обновление 1/1/2015. Он был помещен в GitHub некоторое время назад: BCrypt для Delphi.
Бонус 4/16/2015: теперь Scrypt для Delphi