---
title: github-fill
description: 密码复杂度 OceanBase 数据库 Oracle 模式的密码复杂度策略，兼容 Oracle 数据库的密码策略。为了防止恶意的密码攻击，提升数据库的安全性，OceanBase 数据库用户可以根据需要，设置密码的复杂度函数，验证用户登录身份。 功能适用性 本文档仅适用于 OceanBase 数据库 Oracle 模式…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.2.1 LTS

# 密码复杂度

更新时间：2026-07-15 22:01:30

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.2.1/zh-CN/600.manage/500.security-and-permissions/200.identification-and-authentication/200.identification-and-authentication-of-oracle-mode/200.password-complexity-of-oracle-mode.md)  

OceanBase 数据库 Oracle 模式的密码复杂度策略，兼容 Oracle 数据库的密码策略。为了防止恶意的密码攻击，提升数据库的安全性，OceanBase 数据库用户可以根据需要，设置密码的复杂度函数，验证用户登录身份。

#### 功能适用性

本文档仅适用于 OceanBase 数据库 Oracle 模式。目前 OceanBase 数据库社区版仅提供了 MySQL 模式，有关 MySQL 模式下的密码复杂度，参见 [密码复杂度](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000218723)。

## 前提条件

Oracle 模式下，用户可以使用 Profile 中的 `PASSWORD_VERIFY_FUNCTION` 属性来验证密码复杂度是否符合要求。用户需要先创建一个用于校验密码复杂度的 PL Function，需要满足如下接口：

```sql
FUNCTION verify_function (username     IN VARCHAR2,
           password     IN VARCHAR2,
           old_password IN VARCHAR2)
RETURN BOOLEAN;

```

创建用户或修改密码时，会调用该校验函数，根据函数执行结果来判断新密码是否符合复杂度要求。

## 设置密码复杂度并启用密码复杂度验证

OceanBase 数据库的 Oracle 模式提供了 `PASSWORD_VERIFY_FUNCTION` 参数来验证密码复杂度是否符合要求。

`PASSWORD_VERIFY_FUNCTION` 参数允许将 PL 的密码复杂性验证函数作为参数传递给 `CREATE PROFILE` 和 `ALTER PROFIL` 语句。

#### 注意

生产环境建议设置密码长度为 20 位，包括数字、大写字母、小写字母以及特殊字符。密码的复杂度越低，其被破解的可能性就越大，比如包含用户名、使用重复字符等。出于安全性考虑，需确保用户的密码具有较高的复杂度。

1. 使用 `SYS` 用户登录到集群的 Oracle 租户。

   ```shell
   obclient -usys@oracle -h10.xxx.xxx.1 - P2881 -P*******

   ```
 2. 编写 `PASSWORD_VERIFY_FUNCTION` 参数对应的函数并授权。

   以下以设置密码复杂度为如下规则，提供操作指导。

      - 密码长度最小为 8 个字符，最大不超过 256 个字符。
      - 至少包含 1 个大写字母、1 个小写字母和 1 个特殊字符。
      - 密码不能是用户名，不能是用户名的反序，也不能是服务器名。

   示例如下：

   ```shell
   delimiter //

   CREATE OR REPLACE FUNCTION complexity_check
   (password varchar2,
       chars integer := NULL,
       letter integer := NULL,
       upper_c integer := NULL,
       lower_c integer := NULL,
       digit integer := NULL,
       special integer := NULL)
   RETURN boolean IS
       digit_array varchar2(10) := '0123456789';
       alpha_array varchar2(26) := 'abcdefghijklmnopqrstuvwxyz';
       cnt_letter integer := 0;
       cnt_upper integer := 0;
       cnt_lower integer := 0;
       cnt_digit integer := 0;
       cnt_special integer := 0;
       flag boolean := FALSE;
       len INTEGER := NVL(length(password), 0);
       i integer ;
       ch CHAR(1);
   BEGIN
       -- Check that the password length does not exceed 2 * (max DB pwd len)
       -- The maximum length of any DB User password is 128 bytes.
       -- This limit improves the performance of the Edit Distance calculation
       -- between old and new passwords.
   IF len > 256 THEN
       raise_application_error(-20020, 'Password length more than 256');
   END IF;

       -- Classify each character in the password.
       FOR i in 1..len LOOP
           ch := substr(password, i, 1);
           IF ch = '"' THEN
               flag := TRUE;
           ELSIF instr(digit_array, ch) > 0 THEN
               cnt_digit := cnt_digit + 1;
           ELSIF instr(alpha_array, LOWER(ch)) > 0 THEN
               cnt_letter := cnt_letter + 1;
               IF ch = LOWER(ch) THEN
                   cnt_lower := cnt_lower + 1;
               ELSE
                   cnt_upper := cnt_upper + 1;
               END IF;
           ELSE
               cnt_special := cnt_special + 1;
           END IF;
       END LOOP;
       IF flag = 1 THEN
           raise_application_error(-20012, 'password must NOT contain a '
                                                               || 'double-quote character, which is '
                                                               || 'reserved as a password delimiter');
       END IF;
       IF chars IS NOT NULL AND len < chars THEN
           raise_application_error(-20001, 'Password length less than ' ||
                                                               chars);
       END IF;
       IF letter IS NOT NULL AND cnt_letter < letter THEN
           raise_application_error(-20022, 'Password must contain at least ' ||
                                                               letter || ' letter(s)');
       END IF;
       IF upper_c IS NOT NULL AND cnt_upper < upper_c THEN
           raise_application_error(-20023, 'Password must contain at least ' ||
                                                               upper_c || ' uppercase character(s)');
       END IF;
       IF lower_c IS NOT NULL AND cnt_lower < lower_c THEN
           raise_application_error(-20024, 'Password must contain at least ' ||
                                                                   lower_c || ' lowercase character(s)');
       END IF;
       IF digit IS NOT NULL AND cnt_digit < digit THEN
           raise_application_error(-20025, 'Password must contain at least ' ||
                                                                   digit || ' digit(s)');
       END IF;
       IF special IS NOT NULL AND cnt_special < special THEN
           raise_application_error(-20026, 'Password must contain at least ' ||
                                                                   special || ' special character(s)');
       END IF;
       RETURN(TRUE);
       END;
   //

   CREATE OR REPLACE FUNCTION verify_function
   (username varchar2,
       password varchar2,
       old_password varchar2)
       -- 此例中自定义了三个函数参数---用户名 username、新密码 password 和旧密码 old_password
   RETURN boolean IS
       differ integer;
       pw_lower varchar2(256);
       db_name varchar2(40);
       i integer;
       simple_password varchar2(10);
       reverse_user varchar2(32);
   BEGIN
       IF NOT complexity_check(password, 8, NULL, 1, 1, NULL, 1) THEN
           RETURN(FALSE);
       END IF;

       -- Check if the password contains the username
       pw_lower := LOWER(password);
       IF instr(pw_lower, LOWER(username)) > 0 THEN
           raise_application_error(-20002, 'Password contains the username');
       END IF;

       -- Check if the password contains the username reversed
       reverse_user := '';
       FOR i in REVERSE 1..length(username) LOOP
           reverse_user := reverse_user || substr(username, i, 1);
       END LOOP;
       IF instr(pw_lower, LOWER(reverse_user)) > 0 THEN
           raise_application_error(-20003, 'Password contains the username ' ||
                                                                                                   'reversed');
       END IF;

       -- Check if the password contains the server name
       db_name := 'oceanbase';
       IF instr(pw_lower, LOWER(db_name)) > 0 THEN
           raise_application_error(-20004, 'Password contains the server name');

       END IF;

       -- Check if the password contains 'oracle'
       IF instr(pw_lower, 'oracle') > 0 THEN
           raise_application_error(-20006, 'Password too simple');
       END IF;

       RETURN(TRUE);
   END;
   //
   delimiter ;

   obclient> GRANT EXECUTE ON verify_function TO PUBLIC;
   obclient> CREATE PUBLIC SYNONYM verify_function FOR sys.verify_function;

   ```

   创建函数的相关操作，请参见 [创建函数](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000221201)。
 3. 在 User 的 Profile 中，指定 `PASSWORD_VERIFY_FUNCTION` 参数，启用密码复杂度验证。

   语句如下：

   ```shell
   obclient> ALTER PROFILE profile_name LIMIT PASSWORD_VERIFY_FUNCTION verify_function;

   ```

   其中，`profile_name` 可以使用您自定义的 Profile，也可以使用 `DEFAULT` Profile。

   使用 `DEFAULT` Profile 指定 `PASSWORD_VERIFY_FUNCTION` 参数的示例如下：

   ```shell
   obclient> ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION verify_function;
   Query OK, 0 rows affected

   ```

   更多 `ALTER PROFILE` 语句的详细信息，参见 [ALTER PROFILE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000222089)。
 4. 完成后，您可以执行以下语句，确认密码复杂度验证是否开启。

   返回值为 `NULL` 则表示密码复杂度验证未开启，值为刚刚指定的函数则表示密码复杂度验证已开启。

   ```shell
   obclient> SELECT LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME='PASSWORD_VERIFY_FUNCTION' AND PROFILE='profile_name';

   ```

   示例如下：

   ```shell
   obclient> SELECT LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME='PASSWORD_VERIFY_FUNCTION' AND PROFILE='DEFAULT';
   +-----------------+
   | LIMIT           |
   +-----------------+
   | VERIFY_FUNCTION |
   +-----------------+
   1 row in set

   ```

## 验证密码复杂度的设置是否有效

1. 使用 `SYS` 用户登录集群的 Oracle 租户。

   ```
 2. 分别使用符合要求的密码和不符合要求的密码创建用户 `sectest1`。

   ```shell
   obclient> CREATE USER sectest1 IDENTIFIED BY ******;
   ERROR-20023: Password must contain at least 1 uppercase character(s)

   obclient> CREATE USER sectest1 IDENTIFIED BY ******;
   ERROR-20002: Password contains the username

   obclient> CREATE USER sectest1 IDENTIFIED BY ******;
   Query OK, 0 rows affected

   ```

## 查看密码复杂度规则

密码复杂度设置成功后，如果下次需要查看具体的复杂度规则，可以通过查询函数中的内容来获取。

方法如下：

1. 使用 SYS 用户登录集群的 Oracle 租户。

   ```
 2. 通过 `DBA_SOURCE` 视图查找对应的函数。

   `DBA_SOURCE` 视图记录了系统中所有的存储过程和函数。

   更多 `DBA_SOURCE` 视图及其字段的说明，参见 [DBA_SOURCE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000219391)。

   示例如下：

   ```shell
   obclient> SELECT OWNER,NAME,TYPE FROM DBA_SOURCE WHERE TYPE='FUNCTION';
   +-------+------------------+----------+
   | OWNER | NAME             | TYPE     |
   +-------+------------------+----------+
   | SYS   | COMPLEXITY_CHECK | FUNCTION |
   | SYS   | STRING_DISTANCE  | FUNCTION |
   | SYS   | VERIFY_FUNCTION  | FUNCTION |
   +-------+------------------+----------+
   3 rows in set

   ```
 3. 通过 `USER_SOURCE` 视图查看当前用户拥有的函数 `VERIFY_FUNCTION` 的内容。

   `USER_SOURCE` 视图记录了系统中当前用户拥有的所有存储过程和函数。

   更多 `USER_SOURCE` 视图及其字段的说明，参见 [USER_SOURCE](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000219311)。

   示例如下：

   ```shell
   obclient>SELECT TEXT FROM USER_SOURCE WHERE NAME='VERIFY_FUNCTION' AND
        TYPE='FUNCTION'\G
   *************************** 1. row ***************************
   TEXT: FUNCTION verify_function
        (username varchar2,
            password varchar2,
            old_password varchar2)
            -- 此例中自定义了三个函数参数---用户名 username、新密码 password 和旧密码 old_password
        RETURN boolean IS
            differ integer;
            pw_lower varchar2(256);
            db_name varchar2(40);
            i integer;
            simple_password varchar2(10);
            reverse_user varchar2(32);
        BEGIN
            IF NOT complexity_check(password, 8, NULL, 1, 1, NULL, 1) THEN
                RETURN(FALSE);
            END IF;

            END IF;

            RETURN(TRUE);
        END
   1 row in set

   ```

更多函数管理的相关操作，参见 [管理存储过程和函数](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000221202)。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
