PostgreSQL使用者密碼如何透過md5加密儲存,是否加了salt

yzs87發表於2019-03-08

一、PG使用者的密碼如何透過md5加密,並且是否加了salt?本文將從原始碼角度跟蹤分析。

PG使用者透過md5加密時,加了salt,而這個salt是使用者名稱字串。

二、原始碼分析

CreateRole:
	shadow_pass = encrypt_password(Password_encryption, stmt->role,password);
	|--	pg_md5_encrypt(password, role, strlen(role),encrypted_password);
	|	|--	memcpy(crypt_buf, passwd, passwd_len);
	|	|	memcpy(crypt_buf + passwd_len, role, strlen(role));
	|	|	strcpy(buf, "md5");
	|--	|--	pg_md5_hash(crypt_buf, passwd_len + salt_len, buf + 3);
	new_record[Anum_pg_authid_rolpassword - 1] =CStringGetTextDatum(shadow_pass);

三、gdb跟蹤


1、在函式encrypt_password上打斷點,然後客戶端執行:create user yzs with password '123456';建立帶密碼的使用者,觀察是否預設使用md5。

postgres=# create user yzs with password '123456';

2、堆疊資訊

Breakpoint 1, encrypt_password (target_type=PASSWORD_TYPE_MD5, role=0x99c3b3c "yzs", password=0x99c3b4c "123456") at crypt.c:111
111		PasswordType guessed_type = get_password_type(password);
(gdb) bt
#0  encrypt_password (target_type=PASSWORD_TYPE_MD5, role=0x99c3b3c "yzs", password=0x99c3b4c "123456") at crypt.c:111
#1  0x0827b7a2 in CreateRole (pstate=0x9a0d804, stmt=0x99c3bbc) at user.c:412
#2  0x0840fc18 in standard_ProcessUtility (pstmt=0x99c3c14, queryString=0x99c31dc "create user yzs with password '123456';", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, 
    dest=0x99c3d74, completionTag=0xbf9119e6 "") at utility.c:722
#3  0x0840f42a in ProcessUtility (pstmt=0x99c3c14, queryString=0x99c31dc "create user yzs with password '123456';", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, 
    dest=0x99c3d74, completionTag=0xbf9119e6 "") at utility.c:357
#4  0x0840e6ea in PortalRunUtility (portal=0x9a20634, pstmt=0x99c3c14, isTopLevel=1 '\001', setHoldSnapshot=0 '\000', dest=0x99c3d74, completionTag=0xbf9119e6 "") at pquery.c:1178
#5  0x0840e8b7 in PortalRunMulti (portal=0x9a20634, isTopLevel=1 '\001', setHoldSnapshot=0 '\000', dest=0x99c3d74, altdest=0x99c3d74, completionTag=0xbf9119e6 "") at pquery.c:1324
#6  0x0840ded2 in PortalRun (portal=0x9a20634, count=2147483647, isTopLevel=1 '\001', run_once=1 '\001', dest=0x99c3d74, altdest=0x99c3d74, completionTag=0xbf9119e6 "") at pquery.c:799
#7  0x08408692 in exec_simple_query (query_string=0x99c31dc "create user yzs with password '123456';") at postgres.c:1099
#8  0x0840c5d4 in PostgresMain (argc=1, argv=0x997edc4, dbname=0x997ecf4 "postgres", username=0x99558cc "postgres") at postgres.c:4088
#9  0x083864e6 in BackendRun (port=0x9978038) at postmaster.c:4409
#10 0x08385c5d in BackendStartup (port=0x9978038) at postmaster.c:4081
#11 0x083822d9 in ServerLoop () at postmaster.c:1755
#12 0x083819d6 in PostmasterMain (argc=3, argv=0x9953810) at postmaster.c:1363
#13 0x082dfb60 in main (argc=3, argv=0x9953810) at main.c:228
(gdb) n
114		if (guessed_type != PASSWORD_TYPE_PLAINTEXT)
(gdb) 
123		switch (target_type)
(gdb) 
126				encrypted_password = palloc(MD5_PASSWD_LEN + 1);
(gdb) 
128				if (!pg_md5_encrypt(password, role, strlen(role),
(gdb) s
pg_md5_encrypt (passwd=0x99c3b4c "123456", salt=0x99c3b3c "yzs", salt_len=3, buf=0x9a0d984 "") at md5.c:326
326		size_t		passwd_len = strlen(passwd);
(gdb) n
329		char	   *crypt_buf = malloc(passwd_len + salt_len + 1);
(gdb) 
332		if (!crypt_buf)
(gdb) 
339		memcpy(crypt_buf, passwd, passwd_len);
(gdb) 
340		memcpy(crypt_buf + passwd_len, salt, salt_len);
(gdb) p crypt_buf
$1 = 0x9979e68 "123456A"
(gdb) n
342		strcpy(buf, "md5");
(gdb) p crypt_buf
$2 = 0x9979e68 "123456yzsנ\tQ"
(gdb) n
343		ret = pg_md5_hash(crypt_buf, passwd_len + salt_len, buf + 3);
(gdb) p crypt_buf
$3 = 0x9979e68 "123456yzsנ\tQ"
(gdb) n
345		free(crypt_buf);
(gdb) p crypt_buf
$4 = 0x9979e68 "123456yzsנ\tQ"
(gdb) n
347		return ret;
(gdb) 
348	}
(gdb) p ret
$5 = 1 '\001'
(gdb) n
encrypt_password (target_type=PASSWORD_TYPE_MD5, role=0x99c3b3c "yzs", password=0x99c3b4c "123456") at crypt.c:131
131				return encrypted_password;
(gdb) 
146	}
(gdb) 
CreateRole (pstate=0x9a0d804, stmt=0x99c3bbc) at user.c:415
415					CStringGetTextDatum(shadow_pass);
(gdb) p shadow_pass
$6 = 0x9a0d984 "md5aed8080c314507e15542d5e9519723a8"

3、從pg_authid表中觀察該使用者經過md5加過密的密碼值,可以看出和堆疊資訊中看到的一樣

postgres=# select *from pg_authid where rolname='yzs';
 rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit |             rolpassword             | rolvaliduntil 
---------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------------------------------+---------------
 yzs     | f        | t          | f             | f           | t           | f              | f            |           -1 | md5aed8080c314507e15542d5e9519723a8 | 
(1 row)



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2637913/,如需轉載,請註明出處,否則將追究法律責任。

相關文章