博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL md5 auth method introduce, with random salt protect
阅读量:6981 次
发布时间:2019-06-27

本文共 4767 字,大约阅读时间需要 15 分钟。

在上一篇BLOG中介绍了不要在pg_hba.conf中使用password认证方法, 除非你的客户端和数据库服务器之间的网络是绝对安全的.

MD5方法,认证过程 :
Encrypting Passwords Across A NetworkThe MD5 authentication method double-encrypts the password on the client before sending it to the server. It first MD5-encrypts it based on the user name, and then encrypts it based on a random salt sent by the server when the database connection was made. It is this double-encrypted value that is sent over the network to the server. Double-encryption not only prevents the password from being discovered, it also prevents another connection from using the same encrypted password to connect to the database server at a later time.
数据库服务器给客户端连接进程发送认证请求包 : 
src/backend/libpq/auth.c
/* * Send an authentication request packet to the frontend. */static voidsendAuthRequest(Port *port, AuthRequest areq){        StringInfoData buf;        pq_beginmessage(&buf, 'R');        pq_sendint(&buf, (int32) areq, sizeof(int32));        /* Add the salt for encrypted passwords. */        if (areq == AUTH_REQ_MD5)                pq_sendbytes(&buf, port->md5Salt, 4);#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)        /*         * Add the authentication data for the next step of the GSSAPI or SSPI         * negotiation.         */        else if (areq == AUTH_REQ_GSS_CONT)        {                if (port->gss->outbuf.length > 0)                {                        elog(DEBUG4, "sending GSS token of length %u",                                 (unsigned int) port->gss->outbuf.length);                        pq_sendbytes(&buf, port->gss->outbuf.value, port->gss->outbuf.length);                }        }#endif        pq_endmessage(&buf);        /*         * Flush message so client will see it, except for AUTH_REQ_OK, which need         * not be sent until we are ready for queries.         */        if (areq != AUTH_REQ_OK)                pq_flush();}
服务端接收到客户端发过来的经过salt和原密码md5合成后的md5, 校验是否正确.
src/backend/libpq/crypt.c
* crypt.c *        Look into the password file and check the encrypted password with *        the one passed in from the frontend.intmd5_crypt_verify(const Port *port, const char *role, char *client_pass){        int                     retval = STATUS_ERROR;        char       *shadow_pass,                           *crypt_pwd;... 略.        /*         * Compare with the encrypted or plain password depending on the         * authentication method being used for this connection.         */        switch (port->hba->auth_method)        {                case uaMD5:                        crypt_pwd = palloc(MD5_PASSWD_LEN + 1);                        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;                                }                        }                        else                        {                                /* stored password is plain, double-encrypt */                                char       *crypt_pwd2 = palloc(MD5_PASSWD_LEN + 1);                                if (!pg_md5_encrypt(shadow_pass,                                                                        port->user_name,                                                                        strlen(port->user_name),                                                                        crypt_pwd2))                                {                                        pfree(crypt_pwd);                                        pfree(crypt_pwd2);                                        return STATUS_ERROR;                                }                                if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"),                                                                        port->md5Salt,                                                                        sizeof(port->md5Salt),                                                                        crypt_pwd))                                {                                        pfree(crypt_pwd);                                        pfree(crypt_pwd2);                                        return STATUS_ERROR;                                }                                pfree(crypt_pwd2);                        }                        break;... 略.
[参考]
1. src/backend/libpq/auth.c
2. src/backend/libpq/crypt.c
3. 
4. 
5. 

转载地址:http://dmnpl.baihongyu.com/

你可能感兴趣的文章
通过Servlet 将服务器硬盘图片 展示到浏览器
查看>>
linux_nand_driver
查看>>
语义化的软件版本号规则,你是否真的了解软件的版本号
查看>>
[通俗易懂]理解“委托”
查看>>
sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)...
查看>>
xocodebulid 自动化打包 解决提示 ld: library not found for -lPods 问题
查看>>
LPEG
查看>>
python none,null,,,,,类型
查看>>
HDU 3360 National Treasures 奇偶匹配的最低点覆盖
查看>>
/lib /usr/lib /usr/local/lib区别
查看>>
HDU - 5008 Boring String Problem (后缀数组+二分法+RMQ)
查看>>
Swift - 实现点击UITableView单元格时自动展开单元格
查看>>
Cocos2d-x3.0 Button
查看>>
图解.NET Stack和Heap的本质区别
查看>>
Matlab中struct的用法
查看>>
Mysql LIMIT如何正确对其进行优化
查看>>
Spring10种常见异常解决方法
查看>>
近期小结
查看>>
glog 使用
查看>>
C#中的线程(三) 使用多线程
查看>>