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

一、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 | rolbypa***ls | rolconnlimit |             rolpassword             | rolvaliduntil
---------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------------------------------+---------------
 yzs     | f        | t          | f             | f           | t           | f              | f            |           -1 | md5aed8080c314507e15542d5e9519723a8 |
(1 row)

原文地址:https://blog.51cto.com/yanzongshuai/2360292

时间: 2024-11-13 09:15:48

PostgreSQL用户密码如何通过md5加密存储,是否加了salt的相关文章

密码、文件MD5加密,密码sha256、sha384、sha512Hex等加密

package encryption; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.util.Arrays; import org.apache.commons.code

[android] 手机卫士保存密码时进行md5加密

一般的手机没有root权限,进不去data/data目录,当手机刷机了后,拥有root权限,就可以进入data/data目录,查看我们保存的密码文件,因此我们需要对存入的密码进行MD5加密 获取MessageDigest信息摘要器对象,调用MessageDigest.getInstance(“md5”),参数:规则 调用MessageDigest对象的digest(bytes)方法,得到加密的byte[] 数组,参数:byte[] 数组,调用String对象的getBytes()方法获取到字节数

android md5加密与rsa加解密实现代码

import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException; public class MD5 {/* * MD5加密 */  public static String getDigest(String str) { MessageDigest messageDigest = null; try { mess

为什么密码要以MD5值存储在数据库

1,为什么数据库中保存的是密码的MD5值,而不是明文? 首先我们确认的一点是:MD5肯定比明文要安全一些(当然肯定不是最安全的) 如果数据库存储的是明文,如果数据库被黑了,那么明文密码泄露之后,普通用户都可以很容易登录. 但是如果存储的是MD5值,就算泄露了,普通用户也没法登录.因为页面上登录时要求输入明文. 当然程序员可以直接调用登录接口,传递密码MD5值也可以登录. 另外一点:明文包含更多的信息(相对于其MD5值),比如明文可能是银行密码,或者包含出生日期等,这些都是敏感信息. 使用MD5之

【iOS】MD5加密与网络数据安全

在做网络应用程序的时候, 时时刻刻要保证用户数据的安全, 因此要加密. MD5算法在国内用的很多. MD5算法的特点: *同样的数据加密结果是一样的.(32个字符) *不可逆的.(不能逆向解密) *可用于文件校验/指纹识别. MD5算法是公开的,iOS中已经包装好了MD5算法. 可以将其写成字符串的分类: - (NSString *)md5String { const char *string = self.UTF8String; int length = (int)strlen(string)

手机安全卫士------手机防盗页面之自定义对话框&MD5加密

功能需求: 用户点击主页面上的"手机防盗"按钮时,判断用户是否设置过密码. 如果没有设置过,则弹出输入密码对话框 如果设置过了,则弹出设置密码对话框 用户的密码要进行MD5加密之后再存储在内存中 技术点: - 自定义对话框的使用 - MD5加密的实现方式 - SharedPreferences的读写操作 自定义对话框 1.在layout目录下创建一个布局文件,把自定义的对话框布局设置成功 具体代码实现如下 设置密码对话框的布局代码: <?xml version="1.0

一个简单的后台与数据库交互的登录与注册[sql注入处理,以及MD5加密]

一.工具: vs2013[因为我现在用的也是2013,版本随便你自己开心] sql2008[准备过久升级] 二.用到的语言: HTML+CSS+Jquery+Ajax+sqlserver HTML[相当于一个人] css[要穿衣服] Jquery[人要做一些动作,Jquery是对js一些常用方法的封装] Ajax[建立前端页面与数据库的交互] sqlserver[数据库] 三.过程 html部分代码: 1 <body> 2 <div id="header"> 3

Java 语言实现 MD5 加密

Java 语言实现 MD5 加密 背景说明 在实际项目中,为了安全性考虑,经常要求账号密码是以加密后的密文形式,保存到数据库中. 这样,即使有人获取到了数据库中的密文密码,也不知道明文密码信息是什么,从而防止系统被恶意访问. 密码加密有很多种方式,比如:Base64,DSA,RSA,MD5,SHA128,SHA256,SHA512等加密方式. 本文主要讲述 MD5 加密方式. MD5 简介 MD5 消息摘要算法(英文:MD5 Message-Digest Algorithm),一种被广泛使用的密

使用MD5加密的登陆demo

最近接手了之前的一个项目,在看里面登陆模块的时候,遇到了一堆问题.现在记录下来. 这个登陆模块的逻辑是这样的 1 首先在登陆之前,调用后台的UserLoginAction类的getRandomKey方法产生一个随机字符串. 2 在前台获得用户名的登陆密码后,首先是要md5对其加密,之后把加密的结果与之前的随机字符串合并,使用md5再次加密,并把最后的结果作为用户的密码传给后台. 3 后台获得前台的用户名后(用户名全局唯一),先找出这个用户的密码(数据库里的真实密码),先用md5加密,再与第一步产