HighGoDB 用户密码安全策略
发布日期:2021-05-08 12:27:30 浏览次数:23 分类:精选文章

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

目录
环境
系统平台: Linux x86-64 Red Hat Enterprise Linux 7
版本: 4.3.2
文档用途

通过调用函数的方式增强用户密码的安全性 

详细信息

一般来说数据库密码安全管理要考虑以下几个方面 : 

1. 密码过期策略, 决定密码的有效期, 多长时间过期. 

2. 密码复用策略, 密码修改时需要对比以前的密码, 多少次以后才可以复用, 或者永不能使用与以前密码相同的密码.

3. 密码长度策略, 密码的最小长度, 太短的话很容易被穷举法破解, 一般至少使用8位以上长度的密码.

4. 密码复杂度策略, 密码包含的字符复杂度, 一般要求包含数字字母大小写以及特殊字符. 另外不要使用与数据库名, 用户名相似或一致的密码.

5. 密码字典过滤, 过滤掉一些用户常用的或者有意义的字符, 也是为了避免密码很容易被穷举破解. 

6. 密码存储策略, 使用加密存储, 不要使用明文存储. 

加密存储在创建用户时使用encrypted password即可. 

如果设置了password_encryption=off, 同时创建用户时不加encrypted, 那么密码将以明文存储.

加密存储方法 : 

highgo=# create role u1 login encrypted password 'highgo';

CREATE ROLE

highgo=# select * from pg_shadow where usename='u1';

 usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls |               passwd                | v

aluntil | useconfig

---------+----------+-------------+----------+---------+--------------+-------------------------------------+--

--------+-----------

 u1      |   131294 | f           | f        | f       | f            | md50a0a7a2ef5607a4424f00e4903877f2e |  

        |

(1 row)

 

7. 密码锁策略, 密码输入错误多少次后锁用户, 多长时间解锁.

HighgoDB不支持密码锁策略.

8. 密码保护策略, 密码输入错误多少次后延迟认证. 可用来防止暴力破解.

 

目前HighgoDB在密码管理这块做得较弱, 以下举例通过函数来实现其中的部分安全策略 : 

创建一个字典表, 用于存放已经使用过的密码的md5值, 以及用来进行暴力破解的密码字典的md5值.

highgo=# create table pwd_dictionary(pwd text unique);

CREATE TABLE

创建一个记录用户最后一次修改密码时间的表. 用于实施密码过期提醒策略.

highgo=# create table user_pwd(rolename name not null unique, pwd_modify_time timestamp not null);

CREATE TABLE

创建用户的函数 : 

highgo=# create or replace function create_role(i_rolename name, i_pwd text) returns void as $$

declare

  v_length int := 8;

begin

  -- 密码长度策略

  if length(i_pwd) < v_length then

    raise notice 'password too short, please use password long than %.', v_length;

    return;

  end if;

  -- 密码复杂度策略, 包含数字, 字母大小写.

  if not(i_pwd ~ '[a-z]' and i_pwd ~ '[A-Z]' and i_pwd ~ '[0-9]') then

    raise notice 'password too simple, please ensure password contain a-z,A-Z and 0-9.';

    return;

  end if;

  -- 密码复用策略, 不允许重复使用已经存在的密码.

  -- 密码字典策略, 不允许使用密码字典中的密码.

  insert into pwd_dictionary(pwd) values (md5(i_pwd));

  -- 插入用户表, 记录用户最后一次修改密码的时间, 用于密码过期策略

  insert into user_pwd(rolename, pwd_modify_time) values (i_rolename, now());

  -- 创建用户

  execute 'create role '||i_rolename||' encrypted password '||quote_literal(i_pwd);

  raise notice 'create role % successed.', i_rolename;

  return;

end;

$$ language plpgsql strict;

CREATE FUNCTION

 

创建用户密码过短, 不允许创建.

highgo=# select * from create_role('u4','pwd');

NOTICE:  password too short, please use password long than 8.

 create_role

-------------

 

(1 row)

创建用户密码过于简单, 不允许创建.

highgo=# select * from create_role('u4','abcdefee');

NOTICE:  password too simple, please ensure password contain a-z,A-Z and 0-9.

 create_role

-------------

 

(1 row)

创建用户正常.

highgo=# select * from create_role('u4','aA0ffffffff');

NOTICE:  create role u4 successed.

 create_role

-------------

 

(1 row)

创建用户密码与现有密码重复, 不允许创建.

highgo=# select * from create_role('new','aA0ffffffff');

ERROR:  duplicate key value violates unique constraint "pwd_dictionary_pwd_key"

DETAIL:  Key (pwd)=(2b9aa88182d13d35930180b4cc791beb) already exists.

CONTEXT:  SQL statement "insert into pwd_dictionary(pwd) values (md5(i_pwd))"

PL/pgSQL function create_role(name,text) line 17 at SQL statement

修改用户密码的函数 : 

highgo=# create or replace function alter_role_pwd(i_rolename name, i_pwd text) returns void as $$

declare

  v_length int := 8;

begin

  -- 密码长度策略

  if length(i_pwd) < v_length then

    raise notice 'password too short, please use password long than %.', v_length;

    return;

  end if;

  -- 密码复杂度策略, 包含数字, 字母大小写.

  if not(i_pwd ~ '[a-z]' and i_pwd ~ '[A-Z]' and i_pwd ~ '[0-9]') then

    raise notice 'password too simple, please ensure password contain a-z,A-Z and 0-9.';

    return;

  end if;

  -- 密码复用策略, 不允许重复使用已经存在的密码.

  -- 密码字典策略, 不允许使用密码字典中的密码.

  insert into pwd_dictionary(pwd) values (md5(i_pwd));

  -- 更新用户表, 记录用户最后一次修改密码的时间, 用于密码过期策略

  update user_pwd set pwd_modify_time=now() where rolename=i_rolename;

  -- 修改用户密码

  execute 'alter role '||i_rolename||' encrypted password '||quote_literal(i_pwd);

  raise notice 'modify role % password successed.', i_rolename;

  return;

end;

$$ language plpgsql strict;

CREATE FUNCTION

使用该函数修改用户密码

highgo=# select * from alter_role_pwd('u4','new');

NOTICE:  password too short, please use password long than 8.

 alter_role_pwd

----------------

(1 row)

highgo=# select * from alter_role_pwd('u4','new22222222');

NOTICE:  password too simple, please ensure password contain a-z,A-Z and 0-9.

 alter_role_pwd

----------------

 

(1 row)

highgo=# select * from alter_role_pwd('u4','new2222222z2');

NOTICE:  password too simple, please ensure password contain a-z,A-Z and 0-9.

 alter_role_pwd

----------------

 

(1 row)

highgo=# select * from alter_role_pwd('u4','new2222222z2A');

NOTICE:  modify role u4 password successed.

 alter_role_pwd

----------------

 

(1 row)

highgo=# select * from alter_role_pwd('u4','new2222222z2A');

ERROR:  duplicate key value violates unique constraint "pwd_dictionary_pwd_key"

DETAIL:  Key (pwd)=(9a5c46207db775d4d98e64d427481cbc) already exists.

CONTEXT:  SQL statement "insert into pwd_dictionary(pwd) values (md5(i_pwd))"

PL/pgSQL function alter_role_pwd(name,text) line 17 at SQL statement

 

密码过期提醒 : 

因为密码最后一次修改时间已经更新到user_pwd表, 所以结合这个可以在系统crontab中或者nagios监控软件中实施密码过期提醒.

highgo=# select * from user_pwd ;

 rolename |      pwd_modify_time       

----------+----------------------------

 u4      | 2013-05-25 18:21:59.376404

(1 row)

[小结]

1. 为了密码安全性, 在HighgoDB中, 创建用户请使用create_role函数, 不要直接使用create role 命令.

2. 修改用户密码请使用alter_role_pwd函数. 不要直接使用alter role 命令.

登陆【瀚高技术支持平台】,查看更多资料

上一篇:Failed to execute vcredist_x64.exe
下一篇:Win10系统上安装HGDB 3.1.4单机报错

发表评论

最新留言

很好
[***.229.124.182]2025年04月02日 09时12分02秒