Postgresql api属性文件中的MD5哈希数据库密码

Postgresql api属性文件中的MD5哈希数据库密码,postgresql,encryption,md5,java,Postgresql,Encryption,Md5,Java,我有一个与Postgres对话的RESTAPI,现在在api的属性文件中,我们正在硬编码DB密码。 所以我们认为,当在postgres中创建用户角色时,我们可以使用Md5哈希值(或任何其他应该由postgres解密的加密值)作为密码…并且我们可以在api属性文件中使用该值(hased值),而不是硬编码的值 我的问题是,我们是否可以在api dev属性文件中使用Md5哈希值,并且当通过网络发送密码并尝试连接到postgres时,是否会使用它(postgres)解密为实际密码并允许用户连接到DB而无

我有一个与Postgres对话的RESTAPI,现在在api的属性文件中,我们正在硬编码DB密码。 所以我们认为,当在postgres中创建用户角色时,我们可以使用Md5哈希值(或任何其他应该由postgres解密的加密值)作为密码…并且我们可以在api属性文件中使用该值(hased值),而不是硬编码的值


我的问题是,我们是否可以在api dev属性文件中使用Md5哈希值,并且当通过网络发送密码并尝试连接到postgres时,是否会使用它(postgres)解密为实际密码并允许用户连接到DB而无需验证失败????

只是为了澄清-
md5
哈希是而不是加密

19.3.2。密码验证

基于密码的身份验证方法有md5密码。这些 除发送密码的方式外,其他方法的操作方式类似 在连接中,分别是MD5散列文本和明文

如果您担心密码“嗅探”攻击,那么md5 是首选。如果可能,应始终避免使用普通密码。 但是,md5不能与db_user_命名空间功能一起使用。如果 连接受SSL加密保护,然后可以使用密码 安全(尽管SSL证书身份验证可能是更好的选择) 如果依赖于使用SSL)

PostgreSQL数据库密码与操作系统用户密码分开 密码。每个数据库用户的密码都存储在 pg_authid系统目录。可以使用SQL语句管理密码 命令创建用户和更改用户,例如,使用 密码“secret”。如果没有为用户设置密码,则 存储的密码为空,密码身份验证将始终失败 对于该用户

如果为
md5
配置
pg_hba.conf
),则无需显式使用md5()函数将数据库密码保留在属性文件中


出于加密目的,您可以将数据库连接配置为通过SSL工作。请查收

请澄清-
md5
哈希是而不是加密

19.3.2。密码验证

基于密码的身份验证方法有md5密码。这些 除发送密码的方式外,其他方法的操作方式类似 在连接中,分别是MD5散列文本和明文

如果您担心密码“嗅探”攻击,那么md5 是首选。如果可能,应始终避免使用普通密码。 但是,md5不能与db_user_命名空间功能一起使用。如果 连接受SSL加密保护,然后可以使用密码 安全(尽管SSL证书身份验证可能是更好的选择) 如果依赖于使用SSL)

PostgreSQL数据库密码与操作系统用户密码分开 密码。每个数据库用户的密码都存储在 pg_authid系统目录。可以使用SQL语句管理密码 命令创建用户和更改用户,例如,使用 密码“secret”。如果没有为用户设置密码,则 存储的密码为空,密码身份验证将始终失败 对于该用户

如果为
md5
配置
pg_hba.conf
),则无需显式使用md5()函数将数据库密码保留在属性文件中


出于加密目的,您可以将数据库连接配置为通过SSL工作。请查收

TL;DR:除非客户端应用程序能够识别出它是预哈希的,并避免第二次哈希传递,否则不能将哈希密码存储在属性文件中并使用它进行身份验证

如果客户端库确实识别预哈希密码(libpq没有),则哈希密码可以用作真实密码的代理。如果知道散列,就不需要知道真正的密码。这意味着在属性文件中存储散列密码并不比存储原始密码更安全

密码在发送到网络上之前会被再次加密和散列,这样你就不能嗅出网络上看到的内容并使用它进行身份验证


查看源代码,
src/backend/libpq/auth.c
中的
sendAuthRequest

/* Add the salt for encrypted passwords. */
if (areq == AUTH_REQ_MD5)
    pq_sendbytes(&buf, port->md5Salt, 4);
    /*
     * Precompute password salt values to use for this connection. It's
     * slightly annoying to do this long in advance of knowing whether we'll
     * need 'em or not, but we must do the random() calls before we fork, not
     * after.  Else the postmaster's random sequence won't get advanced, and
     * all backends would end up using the same salt...
     */
    RandomSalt(port->md5Salt);
port
src/include/libpq/libpq be.h
中的
struct port
,它具有:

char        md5Salt[4];     /* Password salt */
这由
src/backend/postmaster/postmaster.c
中的
ConnCreate
设置:

/* Add the salt for encrypted passwords. */
if (areq == AUTH_REQ_MD5)
    pq_sendbytes(&buf, port->md5Salt, 4);
    /*
     * Precompute password salt values to use for this connection. It's
     * slightly annoying to do this long in advance of knowing whether we'll
     * need 'em or not, but we must do the random() calls before we fork, not
     * after.  Else the postmaster's random sequence won't get advanced, and
     * all backends would end up using the same salt...
     */
    RandomSalt(port->md5Salt);
现在,在
src/backend/libpq/crypt.c
中的
md5\u crypt\u verify
中验证密码。在这里,我们可以看到,已存储为md5的密码将再次使用会话salt进行散列:

        if (isMD5(shadow_pass))
        {
            /* stored password already encrypted, only do salt */
            if (!pg_md5_encrypt(shadow_pass + strlen("md5"),
                                port->md5Salt,
                                sizeof(port->md5Salt), crypt_pwd))
            {
                pfree(crypt_pwd);
                return STATUS_ERROR;
            }
        }
因此,通过网络发送的散列密码受到会话salt的重放攻击的保护


客户端应用程序是否能够识别预哈希密码以及预期密码的格式取决于客户端库


根据
src/interfaces/libpq/fe auth.c
中的
pg\u password\u sendauth
,libpq前端似乎没有检查预先散列的密码输入。其他客户可能会有所不同。

TL;DR:除非客户端应用程序能够识别出它是预哈希的,并避免第二次哈希传递,否则不能将哈希密码存储在属性文件中并使用它进行身份验证

如果客户端库确实识别预哈希密码(libpq没有),则哈希密码可以用作真实密码的代理。如果知道散列,就不需要知道真正的密码。这意味着将散列密码存储在属性文件中也不会比存储到st更安全