文档章节

PostgreSQL的MD5认证方法

人比黄花瘦太多
 人比黄花瘦太多
发布于 2018/06/12 09:02
字数 2069
阅读 37
收藏 0

认证方法

PostgreSQL支持多种认证方法,包括信任认证、口令认证、kerberos认证、基于身份(Ident)认证、LDAP认证等。根据功能,这些认证方法可以归纳为以下几种认证模式:

1)基于主机的认证:服务器端根据客户端的IP地址、用户名及要访问的数据库来查看配置文件从而判断用户的认证方式。如果是trust,则直接通过认证。

2)口令认证:包含加密和非加密口令认证。合法的用户名和口令可以创建数据库连接,非法用户将被拒绝。

3)操作系统认证:与操作系统集成完成用户认证。数据库中允许的操作系统用户可以不输入数据库用户名和密码直接与数据库连接。

4)第三方认证:包括kerberos认证和ident认证。利用第三方认证服务器来进行认证。

5)SSL加密:利用OpenSSL提供前后端进行安全连接的环境。

口令认证

PostgreSQL的口令认证又分为明文口令(Password)认证和加密口令(MD5)认证。

明文口令认证要求客户端提供一个未加密的口令进行认证,传送过程较简单但安全性较差,一般不建议采用此认证方法。加密口令认证要求客户端提供一个经过MD5加密的口令进行认证,该口令在传送过程中使用了结合salt(服务器发送给客户端的随机数)的单向MD5加密,增强了安全性。

PostgreSQL的数据库口令都存储在系统表pg_authid里,口令可以使用SQL语言命令CREATE USER和ALTER USER等管理(如CREATE USER test WITH PASSWORD '1234';),如果没有明确设置口令,那么存储的口令为空并且该用户的口令认证总会失败。

客户端认证

Postmaster接收到一个用户的连接请求之后会调用ClientAuthentication函数进行客户端认证。该函数只有一个类型为Port的参数,Port结构中存储着客户端的相关信息(如客户端主机名、端口、用户名、数据库名等)。Port结构与客户端认证相关的部分字段如下:

typedef struct Port
{
    ......
    /*认证过程中需要的信息*/
    HbaLine    *hba;
    char		md5Salt[4];
    ......
}Port;

ClientAuthentication函数的执行流程如下:

此函数执行流程归纳如下:

1)调用函数hba_getauthmethod,检查客户端地址、所连接数据库、用户名在文件HBA中是否有能匹配的HBA记录。如果能找到匹配的HBA记录,则将Port结构中的相关认证方法的字段设置为HBA记录中的参数,同时返回状态值STATUS_OK。理论上这个过程不会返回STATUS_ERROR。

2)如果在编译时选择了使用SSL,在这里要先检查客户端是否已提供一个有效的证书(通过Port结构中hba字段的clientcert字段的值来判断)。

3)根据不同的认证方法,进行相应的认证过程。

在认证过程中可能需要和客户端进行多次交互。最后返回值如果为STATUS_OK,则表示认证成功,并将认证成功信息发送回客户端;否则发送认证失败信息。

在认证过程中,服务器端要和客户端交互认证相关的信息,有时不止一次。系统通过函数SendAuthRequest向客户端发送认证请求。

/*
 * Send an authentication request packet to the frontend.
 */
static void
sendAuthRequest(Port *port, AuthRequest areq)
{
	StringInfoData buf;

	CHECK_FOR_INTERRUPTS();

	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();

	CHECK_FOR_INTERRUPTS();
}

此函数实现流程如下:

1)初始化一个buf。

2)把请求信息转化成二进制加入buf。

3)判断是否为MD5认证,是则加入MD5的随机数Salt信息。

4)判断是否激活了GSS或SSPI认证,是则将相关认证信息加入到buf。

5)调用pq_endmessage函数将buf内的信息发送给客户端。

MD5认证

MD5的认证过程如下:

1)调用函数sendAuthRequest发送一个MD5类型的认证请求AUTH_REQ_MD5给客户端。

2)在sendAuthRequest中除了发送认证请求信息之外,还将调用pq_sendbytes函数将长度为4位的随机数md5Salt发送给客户端,并等待客户端回应。

3)客户端首先将用户输入的密码进行一次MD5加密,其中用户名作为salt。然后将服务器发送过来的4位的随机数md5Salt作为salt再进行一次MD5加密,并将结果作为认证信息再次发送给服务器端。

4)服务器端通过函数recv_password_packet获取客户端返回的结果。如果结果值为空,表明客户端没有发送秘钥,返回STATUS_EOF;如果结果值不为空,调用md5_crypt_verify,获取从系统表pg_authid中取出的用户的密码,如果密码是MD5加密过的,那么将随机数md5Salt作为salt进行一次MD5加密;如果密码是未加密的,则进行两次加密,首先是将用户名作为salt进行一次加密,然后将随机数md5Salt作为salt再进行一次MD5加密。将服务器端计算的结果和客户端提交的结果进行比较,如果相等则返回STATUS_OK。

5)如果返回值为STATUS_OK,则执行函数sendAuthRequest将认证成功信息发送到客户端,否则执行函数auth_failed将认证失败信息返回。

假设服务器对客户端的认证方式设置为MD5且认证过程中的步骤均成功,那么客服端与服务器的交互过程可以表述为下:

                                      

PostgreSQL 10版本新特性SCRAM机制

PostgreSQL SCRAM机制目前只支持SCRAM-SHA-256算法。SCRAM相比MD5,可以避免因为数据库存储的加密秘钥泄露导致客户端可以篡改认证协议连接数据库的危险。由于SCRAM和MD5不兼容,二者只能选其一。

实验如下:

MD5:

环境

(服务器端)IP:192.168.100.197
(客户端)  IP:192.168.100.198

修改服务器端配置文件

# postgrsql.conf

listen_addresses = '*'
# pg_hba.conf

host     all             all             192.168.100.198/32      md5

服务器端启动数据库后,创建test用户并查看其在系统表中的密码

postgres=# create role test encrypted password 'test' login;
CREATE ROLE
postgres=# \x
Expanded display is on.
postgres=# select * from pg_authid;
......
-[ RECORD 2 ]--+------------------------------------
rolname        | test
rolsuper       | f
rolinherit     | t
rolcreaterole  | f
rolcreatedb    | f
rolcanlogin    | t
rolreplication | f
rolbypassrls   | f
rolconnlimit   | -1
rolpassword    | md505a671c66aefea124cc08b76ea6d30bb
rolvaliduntil  | 

客户端连接服务器端:

[postgres@localhost ~]$ psql -U test -d postgres -h 192.168.100.197 -p 5432
Password for user test: 
psql (9.5.6)
Type "help" for help.

postgres=> 

SCRAM:

环境

(服务器端)IP:192.168.100.200
(客户端)  IP:192.168.100.154

修改服务器端配置文件

# postgrsql.conf

listen_addresses = '*'
password_encryption = scram-sha-256             # md5, scram-sha-256, or plain
# pg_hba.conf

host    all             all             192.168.100.154/32      scram-sha-256

服务器端启动数据库后,创建test用户并查看其在系统表中的密码

[postgres@localhost data]$ psql
psql (10beta4)
Type "help" for help.

postgres=#  create role test encrypted password 'test' login;
CREATE ROLE
postgres=# \x
Expanded display is on.
postgres=# select * from pg_authid;
......
-[ RECORD 7 ]--+----------------------------------------------------------------
----------------------------------------------------------------------
rolname        | test
rolsuper       | f
rolinherit     | t
rolcreaterole  | f
rolcreatedb    | f
rolcanlogin    | t
rolreplication | f
rolbypassrls   | f
rolconnlimit   | -1
rolpassword    | SCRAM-SHA-256$4096:TjtqQYHg2cZRAQITd840tg==$a+MZR0WAUviGHiMNJ4E
kl21WOKYh3nH1RdlGv+I4RqI=:6D1gsKie0mBOsIE3+7FXBVAi6KlOQ/ZSgQFsy6TDie4=
rolvaliduntil  | 

客户端连接服务器端:

[postgres@localhost ~]$ psql -U test -d postgres -h 192.168.100.200 -p 5432
Password for user test: 
psql (10beta4)
Type "help" for help.

postgres=> 

由上述可知服务器端收到客户端的认证信息后对比存储在系统表中的 md5加密后的密码, 如果一致,就会通过认证。所以MD5存储的密码直接存储于数据库的系统表中,就会有安全问题。 而scram机制认证的服务器端存储了多次加密后的秘钥,加密方法不可逆。如果这个多次加密后的密钥被获取,也不会通过认证。

参考:《PostgreSQL数据库内核分析》

© 著作权归作者所有

人比黄花瘦太多
粉丝 9
博文 7
码字总数 19401
作品 0
济南
私信 提问
关于连接PostgreSQL时提示 FATAL: password authentication failed for user "连接用户名" 的解决办法【自己试验通过】

借鉴 https://my.oschina.net/u/3371661/blog/3040763 一直以为是密码设错了,其它应该是权限问题【个人理解】 alter role postgres with password '123'; 解决方法 1、编辑pg_hba.conf,将m......

dragon_tech
04/23
14
0
fedora 20中安装postgresql数据库

在fedora 20中在我2014-8-27日安装pg时,pg版本是9.3.5.1我不知是会由pg开发组自动更新还是别的,但安装后一般是最新的版本了。安装: yum install postgresql yum install postgresql-serv...

上海李浩
2014/08/27
769
1
关于连接PostgreSQL时提示 FATAL: password authentication failed for user "连接用户名" 的解决办法

关于连接PostgreSQL时提示 FATAL: password authentication failed for user "连接用户名" 的解决方法 今天帮一个同学解决了一个FATAL: password authentication failed for user "连接用户名......

dragon_tech
04/22
34
0
PostgreSQL远程连接配置管理/账号密码分配(解决:致命错误: 用户 "postgres" Ident 认证失败)

问题:致命错误: 用户 "postgres" Ident 认证失败 说明:这个是由于没有配置远程访问且认证方式没改造成的,只需要更改使用账号密码认证即可。 解决:找到pghba.conf(find / -name pghba.co...

easonjim
2018/05/18
0
0
Centos7安装和配置Postgresql数据库及Navicat连接(超全面)

Postgresql官网Linux Red Hat族系统的Postgresql的下载安装地址: https://www.postgresql.org/download/linux/redhat/ 1.安装最新版 进入网址,可以根据提示安装最新的Postgresql11: 对应的...

panyunxing
07/16
22
0

没有更多内容

加载失败,请刷新页面

加载更多

centos7 linuxdeployqt qt5.13.1 打包程序

原文链接:https://www.cnblogs.com/linuxAndMcu/p/11016322.html 一、简介 linuxdeployqt 是Linux下的qt打包工具,可以将应用程序使用的资源(如库,图形和插件)复制到二进制运行文件所在的...

shzwork
昨天
4
0
IDEA 配置Springboot项目热部署

实现的方式概述 注意以下的热部署方式在IDEA是默认没有打开自动编译的,手动编译需要快捷键(Ctrl+Shift+F9),自动编译的修改配置如下:(注意刷新不要太快,会有1-2秒延迟) File-Settings-C...

小强的进阶之路
昨天
9
0
免费数据分析工具:secsoso

前段时间思考了理想数据分析平台,之后我们根据这个思路开发了spl语言并提供了一个数据分析平台,这个平台主要用在搜索ES,数据库索引中的数据。但后来发现对文件的事后处理也是个非常重要的...

赛克蓝德
昨天
5
0
暗黑2不能正常启动?带你轻松使用WIN10运行游戏

暗黑破坏神2这款游戏由于年代比较久远,所以设置启动这方面与现在的大部分游戏有很大差距,由于当初完美运行暗黑2是当年使用最多的XP系统,在使用现在大多数玩家使用的WIN7到WIN10系统常会出...

太空堡垒185
昨天
6
0
maven项目对象模型(二)

1.4.4.传递性依赖 一个传递性依赖就是一个依赖的依赖。如果project-a依赖于project-b,而后者接着依赖于project-c,那么project-c就是被认为是project-a的传递性依赖。如果project-c依赖于p...

万建宁
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部