#c# #.net #postgresql #.net-5
Вопрос:
Я хочу создать пользователя Postgres с помощью команды «СОЗДАТЬ ПОЛЬЗОВАТЕЛЯ» и уже хэшированного дайджеста для пароля. После долгих поисков я думал, что это возможно только с MD5, пока не нашел эту ссылку. Я проверил, что это работает так:
CREATE USER test_user WITH LOGIN PASSWORD 'SCRAM-SHA-256$4096:H45 UIZiJUcEXrB9SHlv5Q==$I0mc87UotsrnezRKv9Ijqn/zjWMGPVdy1zHPARAGfVs=:nSjwT9LGDmAsMo GqbmC2X/9LMgowTQBjUQsl45gZzA=';
Затем я могу войти в этого пользователя с паролем, о котором в статье не обязательно говорится, но это «postgres». Теперь, когда я знаю, что это возможно, как с помощью .NET 5 я могу создать дайджест scram-sha-256, который будет принят Postgres 13? Я видел другие статьи Postgres, в которых используется устаревший хэш MD5, где имя пользователя соединяется с паролем перед хэшированием. Должно ли это произойти и с новым scram-sha-256? Я нигде не мог найти много информации на эту тему.
Комментарии:
1. У меня нет ответа на ваш вопрос, но вот ссылка, которая более подробно описывает строку пароля для удаления: postgresql.org/docs/13/catalog-pg-authid.html (см. нижнюю часть этой страницы). Кроме того, я думаю, вы могли бы посмотреть исходный код PostgreSQL, чтобы узнать, как шифруется пароль при установке пароля с
password
помощью команды или при создании пользователя сcreateuser someuser --login --pwprompt
помощью .
Ответ №1:
Я не знаю, как сгенерировать дайджест scram-sha-256 с помощью .NET 5. Однако, если дайджест scram-sha-256-это все, что вам нужно, вы можете использовать обходной путь, создав фиктивного пользователя postgres локально и повторив зашифрованный пароль с createuser
помощью команды.
Например (обычно вы запускаете это как пользователь Linux postgres: su postgres
):
$ createuser dummyuser -e --pwprompt
Enter password for new role:
Enter it again:
SELECT pg_catalog.set_config('search_path', '', false);
CREATE ROLE dummyuser PASSWORD 'SCRAM-SHA-256$4096:VnimR0aOywxZzY82nzy9Fg==$qF9uMCU6YsKoecvRjP8jSmZZxrXgn5VwzhHwfoWo5Xg=:xGYfBUvGsu9mZFiq1nSFaHi7uN8n47IDwHO32IeK9io=' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
Теперь вы можете просто скопировать дайджест в свой запрос. Конечно, это работает только в том случае, если вам не нужно динамически генерировать дайджест с помощью .NET.
Не забудьте удалить фиктивного пользователя:
$ dropuser dummyuser
Кроме того, в случае, если ваша локальная база данных postgres все еще использует/генерирует md5, вам необходимо изменить ее на «убирайся», используя следующий запрос, выполненный от имени суперпользователя postgres:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();
Однако, если вы хотите динамически создавать дайджест с помощью .NET, я рекомендую вам ознакомиться с исходным кодом createuser
команды…
Обновление через день:
Вот конкретный исходный код createuser
команды, которая шифрует пароль в строку scram-sha-256:
Чтобы облегчить жизнь, вот ссылки на функции (возможно, не все), которые вызывает вышеуказанная функция
- https://github.com/postgres/postgres/blob/6beb38cfc9ddd4cd3d2eb5402981ebdd69a618b4/src/common/saslprep.c#L1023-L1245
- https://github.com/postgres/postgres/blob/6beb38cfc9ddd4cd3d2eb5402981ebdd69a618b4/src/common/scram-common.c#L160-L274
Вы должны иметь возможность переписать этот код на .NET или любом другом языке. Надеюсь, это поможет!
Комментарии:
1. Да, я думаю, что вы правы, и я подумал, что, возможно, мне тоже придется пойти по этому пути в данный момент. В C# не так много библиотек SASL, которые я с удовольствием использую. Хорошо то, что в исходном коде, который вы связали, все недопустимые символы нормализации Юникода находятся в одном месте, и я пытался перечислить их все со страницы документов RFC3454. Это быстро превращалось в кошмар. Единственное, о чем я задаюсь вопросом, действительно ли мне нужно все это делать, если я использую SSL Postgres, а мой сервер базы данных не является общедоступным.
2. Возможно, я просто добавляю уровни безопасности и создаю для себя ненужную работу. Мне нужно будет подумать об этом, но если я перенесу его на C#, я сделаю код доступным для других.