暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL用户密码如何通过md5加密存储,是否加了salt

yanzongshuaiDBA 2019-03-08
1775

一、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)


          最后修改时间:2019-11-24 18:41:40
          文章转载自yanzongshuaiDBA,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论