Пункт 84. Форматы шифрования паролей
Примечания о форматах шифрования паролей, генерируемых и распознаваемых Apache.
Базовая аутентификация
Существует пять форматов, которые Apache распознает для паролей базовой аутентификации. Обратите внимание, что не все форматы работают на каждой платформе:
- bcrypt
- "$2y$" + результат алгоритма crypt_blowfish. Подробнее об алгоритме см. в исходном файле APR crypt_blowfish.c.
- MD5
- "$apr1$" + результат специфичного для Apache алгоритма с использованием повторяющегося (1000 раз) дайджеста MD5 различных комбинаций случайной 32-битной соли и пароля. Подробнее об алгоритме см. в исходном файле APR apr_md5.c.
- SHA1
- "{SHA}" + дайджест пароля SHA-1 в кодировке Base64. Ненадежный.
- КРИПТ
- Только Юникс. Использует традиционную
crypt(3)
функцию Unix со случайно сгенерированной 32-битной солью (используется только 12 бит) и первыми 8 символами пароля. Ненадежный.
- ОБЫЧНЫЙ ТЕКСТ (т.е. незашифрованный )
- Только Windows и Netware. Ненадежный.
Генерация значений с помощью htpasswd
bcrypt
$ htpasswd -nbB myName myPassword
myName:$2y$05$c4WoMPo3SXsafkva.HHa6uXQZWr7oboPiC2bT/r7q1BB8I2s0BRqC
MD5
$ htpasswd -nbm myName myPassword
myName:$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/
SHA1
$ htpasswd -nbs myName myPassword
myName:{SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE=
КРИПТ
$ htpasswd -nbd myName myPassword
myName:rqXexS6ZhobKA
Генерация значений CRYPT и MD5 с помощью программы командной строки OpenSSL
OpenSSL знает специфичный для Apache алгоритм MD5.
MD5
$ openssl passwd -apr1 myPassword
$apr1$qHDFfhPC$nITSVHgYbDAK1Y0acGRnY0
КРИПТ
openssl passwd -crypt myPassword
qQ5vTYO3c8dsU
Проверка паролей CRYPT или MD5 с помощью программы командной строки OpenSSL
Соль для пароля CRYPT — это первые два символа (преобразованные в двоичное значение). Для проверки myPassword
против
rqXexS6ZhobKA
КРИПТ
$ openssl passwd -crypt -salt rq myPassword
Warning: truncating password to 8 characters
rqXexS6ZhobKA
Обратите внимание, что использование myPasswo
вместо
myPassword
приведет к тому же результату, потому что учитываются только первые 8 символов паролей CRYPT.
Соль для пароля MD5 находится между $apr1$
и следующим $
(как двоичное значение в кодировке Base64 - максимум 8 символов). Для проверки myPassword
против
$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/
MD5
$ openssl passwd -apr1 -salt r31..... myPassword
$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/
Поля пароля базы данных для mod_dbd
Вариант SHA1, вероятно, является наиболее полезным форматом для аутентификации DBD. Поскольку функции SHA1 и Base64 широко доступны, другое программное обеспечение может заполнять базу данных зашифрованными паролями, которые можно использовать при базовой аутентификации Apache.
Чтобы создать пароли базовой аутентификации Apache SHA1 на разных языках:
PHP
'{SHA}' . base64_encode(sha1($password, TRUE))
Джава
"{SHA}" + new sun.misc.BASE64Encoder().encode(java.security.MessageDigest.getInstance("SHA1").digest(password.getBytes()))
Холодный синтез
"{SHA}" & ToBase64(BinaryDecode(Hash(password, "SHA1"), "Hex"))
Рубин
require 'digest/sha1'
require 'base64'
'{SHA}' + Base64.encode64(Digest::SHA1.digest(password))
С или С++
Use the APR function: apr_sha1_base64
питон
import base64
import hashlib
"{SHA}" + format(base64.b64encode(hashlib.sha1(password).digest()))
PostgreSQL (с установленными функциями contrib/pgcrypto)
'{SHA}'||encode(digest(password,'sha1'),'base64')
Дайджест-аутентификация
Apache распознает один формат паролей для дайджест-аутентификации — хеш MD5 строки
user:realm:password
в виде 32-символьной строки шестнадцатеричных цифр. realm
является аргументом Authorization Realm для
AuthName
директивы в apache2.conf.
Поля пароля базы данных для mod_dbd
Поскольку функция MD5 общедоступна, другое программное обеспечение может заполнять базу данных зашифрованными паролями, которые можно использовать для проверки подлинности дайджеста Apache.
Чтобы создать пароли для дайджест-аутентификации Apache на разных языках:
PHP
md5($user . ':' . $realm . ':' .$password)
Джава
byte b[] = java.security.MessageDigest.getInstance("MD5").digest( (user + ":" + realm + ":" + password ).getBytes());
java.math.BigInteger bi = new java.math.BigInteger(1, b);
String s = bi.toString(16);
while (s.length() < 32)
s = "0" + s;
// String s is the encrypted password
Холодный синтез
LCase(Hash( (user & ":" & realm & ":" & password) , "MD5"))
Рубин
require 'digest/md5'
Digest::MD5.hexdigest(user + ':' + realm + ':' + password)
PostgreSQL (с установленными функциями contrib/pgcrypto)
encode(digest( user || ':' || realm || ':' || password , 'md5'), 'hex')