kuj*_*uja 7 .net c# postgresql .net-5
我想使用 CREATE USER 命令和已散列的密码摘要创建一个 Postgres 用户。经过大量搜索,我认为只有 MD5 才可能,直到我找到了这个链接。我已经验证过它的工作原理如下:
CREATE USER test_user WITH LOGIN PASSWORD 'SCRAM-SHA-256$4096:H45+UIZiJUcEXrB9SHlv5Q==$I0mc87UotsrnezRKv9Ijqn/zjWMGPVdy1zHPARAGfVs=:nSjwT9LGDmAsMo+GqbmC2X/9LMgowTQBjUQsl45gZzA=';
然后我可以使用密码登录该用户,文章中不一定提到该密码,但它是“postgres”。现在我知道这是可能的,如何使用 .NET 5 生成 Postgres 13 接受的 scram-sha-256 摘要?我见过其他 Postgres 文章使用过时的 MD5 哈希,其中用户名在哈希之前与密码连接。新的 scram-sha-256 是否也需要这样做?我在任何地方都找不到关于这个主题的太多信息。
我不知道如何使用 .NET 5 生成 scram-sha-256 摘要。但是,如果 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,您必须使用以下查询将其更改为 scram,以 postgres 超级用户身份运行:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();
但是,如果您想使用 .NET 动态创建摘要,我建议您查看该createuser命令的源代码...
一天后更新:
createuser下面是将密码加密为 scram-sha-256 字符串的命令的具体源码:
为了让生活更轻松,这里是上述函数正在调用的函数(可能不是全部)的链接
您应该能够用 .NET 或任何其他语言重写该代码。希望能帮助到你!
有人构建了一个 Go 工具来执行此操作:
https://github.com/supercaracal/scram-sha-256
这是基于该 Go 项目的 python 3 端口:
from base64 import standard_b64encode
from hashlib import pbkdf2_hmac, sha256
from os import urandom
import hmac
import sys
salt_size = 16
digest_len = 32
iterations = 4096
def b64enc(b: bytes) -> str:
    return standard_b64encode(b).decode('utf8')
def pg_scram_sha256(passwd: str) -> str:
    salt = urandom(salt_size)
    digest_key = pbkdf2_hmac('sha256', passwd.encode('utf8'), salt, iterations,
                             digest_len)
    client_key = hmac.digest(digest_key, 'Client Key'.encode('utf8'), 'sha256')
    stored_key = sha256(client_key).digest()
    server_key = hmac.digest(digest_key, 'Server Key'.encode('utf8'), 'sha256')
    return (
        f'SCRAM-SHA-256${iterations}:{b64enc(salt)}'
        f'${b64enc(stored_key)}:{b64enc(server_key)}'
    )
def print_usage():
    print("Usage: provide single password argument to encrypt")
    sys.exit(1)
def main():
    args = sys.argv[1:]
    if args and len(args) > 1:
        print_usage()
    if args:
        passwd = args[0]
    else:
        passwd = sys.stdin.read().strip()
    if not passwd:
        print_usage()
    print(pg_scram_sha256(passwd))
if __name__ == "__main__":
    main()
注意:直接在命令行上传递密码可能会将机密泄露到 shell 历史记录中,使机密在进程输出中对系统上的其他用户可见,等等。如果您使用此工具生成真实的密码哈希值,请注意保护它免受此类影响泄漏(例如,将纯文本密码写入具有安全权限的文本文件,并使用 重定向到脚本的输入python scram256.py < secret-password.txt)。另请注意使用非重复使用的足够长度的随机生成的密码以及超出本问题/答案范围的其他最佳实践。
| 归档时间: | 
 | 
| 查看次数: | 10756 次 | 
| 最近记录: |