较好的实践是,Oracle的密码操作通过profile来实现,而资源则是通过资源消费组来控制,profile其实是种限制。 通过profile来控制密码的使用,大抵有四: 1) 密码的历史 在这里,有两个参数:password_reuse_time和password_reuse_max,比较好的实践是,这两
较好的实践是,Oracle的密码操作通过profile来实现,而资源则是通过资源消费组来控制,profile其实是种限制。
通过profile来控制密码的使用,大抵有四:
1) 密码的历史
在这里,有两个参数:password_reuse_time和password_reuse_max,比较好的实践是,这两个参数当关联起来使用。 如:password_reuse_time=30,password_reuse_max=10,
用户可以在30天以后重用该密码,要求密码必须被改变超过10次。
实验:
会话1:sys
sys@ORCL> create profile p1 limit password_reuse_time 1/1440 password_reuse_max 1;
Profile created.
sys@ORCL> alter user scott profile p1;
User altered.
sys@ORCL> alter user scott password expire;
User altered.
sys@ORCL> alter profile p1 limit password_reuse_time 5/1440 password_reuse_max 1;--5分钟后可重用该密码,但这期间必须要被改成其他密码一次
Profile altered.
sys@ORCL> alter user scott password expire;
User altered.
会话2:scott
scott@ORCL> exit;
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
[Oracle@localhost ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Sep 3 01:11:09 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
idle> conn scott/Oracle
ERROR:
ORA-28001: the password has expired
Changing password for scott
New password: --使用原密码,即Oracle
Retype new password:
ERROR:
ORA-28007: the password cannot be reused
Password unchanged
idle> conn scott/Oracle
ERROR:
ORA-28001: the password has expired
Changing password for scott
New password: --使用新密码,改成think
Retype new password:
Password changed
Connected.
会话1:sys
sys@ORCL> alter user scott password expire;
User altered.
会话2:scott
scott@ORCL> exit;
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
[Oracle@localhost ~]$ sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Sep 3 01:19:04 2012
Copyright (c) 1982, 2005, Oracle. All rights reserved.
idle> conn scott/think
ERROR:
ORA-28001: the password has expired
Changing password for scott
New password: --使用最早的密码,即Oracle
Retype new password:
Password changed
Connected.
scott@ORCL>
2) 密码的登入校验
在这方面,也有两个参数:
failed_login_attempts:锁定前允许的最大失败登录次数
password_lock_time:锁定时间
实验:
会话1:sys
sys@ORCL>删除配置文件 p1 级联;
个人资料已删除。
sys@ORCL> create profile p1 limit failed_login_attempts 1 password_lock_time 1/1440;--失败一次就被锁,被锁1分钟
个人资料已创建。
sys@ORCL>更改用户 scott 个人资料 p1;
用户已更改。
会话2:斯科特
[Oracle@localhost ~]$ sqlplus /nolog
SQL*Plus:版本 10.2.0.1.0 - 于 2012 年 9 月 3 日星期一 01:42:46 生产
版权所有 (c) 1982、2005,Oracle。 保留所有权利。
空闲>康恩·斯科特/思考
错误:
ORA-01017: 用户名/密码无效;登录被拒绝
空闲>康恩·斯科特/甲骨文
错误:
ORA-28000: 帐户已锁定
空闲> conn scott/Oracle --1 分钟之后
已连接。
3)密码的生命周期
同样,这也有两个参数:
password_life_time: 密码的消耗
password_grace_time: 宽限时间,特指将达到消耗前的那些时光
实验:
会话1:sys
sys@ORCL>删除配置文件 p1 级联;
个人资料已删除。
sys@ORCL>创建配置文件 p1 限制password_life_time 2/1440password_grace_time 2/1440;
个人资料已创建。
sys@ORCL>更改用户 scott 个人资料 p1;
用户已更改。
会话2:斯科特
[Oracle@localhost ~]$ sqlplus /nolog
SQL*Plus:版本 10.2.0.1.0 - 于 2012 年 9 月 3 日星期一 01:56:59 投入生产
版权所有 (c) 1982、2005,Oracle。 保留所有权利。
空闲>康恩·斯科特/甲骨文
错误:
ORA-28002: 密码将在 0 天内过期
已连接。
4)密码的复杂性
在$Oracle_HOME/rdbms/admin/utlpwdmg.sql,有一个密码函数,破解,则可控制密码复杂性
现在导出函数摘入如下:
创建或替换函数 verify_function
(用户名 varchar2,
密码 varchar2,
旧密码 varchar2)
返回布尔值 IS
n 布尔值;
m 整数;
不同的整数;
isdigit 布尔值;
ischar 布尔值;
ispunct 布尔值;
数字数组 varchar2(20);
punctarray varchar2(25);
chararray varchar2(52);
开始
数字数组:= '0123456789';
chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
punctarray:='!"#$%&()``* ,-/:;?_';
-- 检查密码是否与用户名相同
IF NLS_LOWER(密码) = NLS_LOWER(用户名) THEN
raise_application_error(-20001, '密码与用户相同或相似');
结束如果;
-- 检查密码的最小长度
IF 长度(密码) raise_application_error(-20002, '密码长度小于4');
结束如果;
-- 检查密码是否太简单。单词词典可能是
-- 维护并进行检查,以免出现这些词
-- 密码太简单了。
IF NLS_LOWER(password) IN ('欢迎', '数据库', '帐户', '用户', '密码', 'Oracle', '计算机', 'abcd') THEN
raise_application_error(-20002, '密码太简单');
结束如果;
-- 检查密码是否至少包含一个字母、一个数字和一个
-- 标点符号。
-- 1. 检查数字
isdigit:=FALSE;
m := 长度(密码);
FOR i IN 1..10 循环
FOR j IN 1..m 循环
IF substr(password,j,1) = substr(digitarray,i,1) THEN
isdigit:=TRUE;
转到 findchar;
结束如果;
结束循环;
结束循环;
IF isdigit = FALSE THEN
raise_application_error(-20003, '密码应至少包含一位数字、一位字符和一位标点符号');
结束如果;
-- 2. 检查字符
>
ischar:=FALSE;
FOR i IN 1..length(chararray) 循环
FOR j IN 1..m 循环
IF substr(密码,j,1) = substr(chararray,i,1) THEN
ischar:=TRUE;
转到 findpunct;
结束如果;
结束循环;
结束循环;
IF ischar = FALSE THEN
raise_application_error(-20003, '密码应至少包含一个
数字、一个字符和一个标点');
结束如果;
-- 3. 检查标点符号
>
ispunct:=FALSE;
FOR i IN 1..length(punctarray) 循环
FOR j IN 1..m 循环
IF substr(password,j,1) = substr(punctarray,i,1) THEN
ispunct:=TRUE;
转到结束搜索;
结束如果;
结束循环;
结束循环;
IF ispunct = FALSE THEN
raise_application_error(-20003, '密码应至少包含一个
数字、一个字符和一个标点');
结束如果;
>
-- 检查密码是否与之前的密码相差至少
-- 3 个字母
如果 old_password 不为 NULL 那么
不同 := 长度(旧密码) - 长度(密码);
IF 绝对值(不同)
IF 长度(密码)
m := 长度(密码);
其他
m := 长度(旧密码);
结束如果;
不同 := abs(不同);
FOR i IN 1..m 循环
IF substr(密码,i,1) != substr(old_password,i,1) THEN
不同 := 不同 1;
结束如果;
结束循环;
如果不同
raise_application_error(-20004, '密码应不同于
至少 3 个字符');
结束如果;
结束如果;
结束如果;
——一切都很好;返回真;
返回(真);
结束;
/