MD5 хешированные пароли: где хешируется?
Я подключаюсь к локальной базе данных PostgreSQL с хешированным паролем md5.
Это работает, но я хочу понять, что происходит под капотом.
Pq хеширует пароль перед отправкой по сети? Как он узнает, нужно ли его хешировать или оставить в виде простого текста? Сервер (в pg_hba.conf) - это тот, кто указывает метод аутентификации того, как пароль передается по соединению.
Есть ли рукопожатие, которое происходит между pq и psql перед передачей строки соединения с паролем?
user := "foo_user"
password := "test"
dbname := "bar"
connectionString := fmt.Sprintf(
"user=%s password=%s dbname=%s",
user,
password,
dbname)
db, err := sql.Open("postgres", connectionString)
Пользователь был создан с паролем через:
ALTER USER foo_user WITH PASSWORD 'test';
И проверил, что пароль хранится как хеш:
postgres=# SELECT rolname, rolpassword from pg_authid;
rolname | rolpassword
-------------------+-------------------------------------
postgres |
pg_signal_backend |
foo_user | md51083525553eab8f4090ada980d2b86e7
(3 rows)
И pg_hba.conf совершенно не изменяется:
# maintenance (custom daily cronjobs, replication, and similar tasks).
#
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
1 ответ
Есть два места, где происходит хеширование паролей, и их не следует путать.
Когда для роли установлен пароль, он объединяется с именем пользователя и затем хэшируется. Этот пароль хранится в
pg_authid
и это фактический пароль, используемый PostgreSQL. PostgreSQL использует не введенный вами пароль, а его хешированную версию, чтобы злоумышленники не могли украсть ваш пароль и затем пытаться использовать его вне PostgreSQL (в случае, если один и тот же пароль используется в нескольких местах).Таким образом, чтобы проникнуть в базу данных, вам на самом деле не нужно знать пароль в виде открытого текста, достаточно "фактического" хешированного пароля.
Есть два места, где может происходить хеширование:
На стороне сервера, если вы используете
CREATE/ALTER ROLE ... PASSWORD 'mypassword';
Это не очень хорошо, потому что пароль передается по сети в виде открытого текста и может отображаться в журнале базы данных.
На стороне клиента, если вы используете
CREATE/ALTER ROLE ... PASSWORD 'hashedpassword';
Это лучше, и это то, что
psql
использует внутренне, если вы используете\password
команда.
Во время аутентификации сеанса, если метод аутентификации, указанный для базы данных и пользователя, требует этого. Затем сервер ответит на запрос соединения
AuthenticationMD5Password
сообщение (см. документацию).Затем клиент хеширует пароль в виде открытого текста, чтобы получить действительный пароль, а затем снова хеширует его со случайной "солью", предоставленной сервером.
Сервер хеширует пароль от
pg_authid
таким же образом и сравнивает результат.