Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - 数据库管理 » 安全 » 保护数据的安全 » 控制数据库访问

 

提高口令安全性

口令在任何数据库安全系统中都是一个重要部分。要做到安全,口令必须不容易被猜到,并且必须难以在用户的硬盘或其它位置得到。SQL Anywhere 口令始终区分大小写。可以使用 verify_password_function 选项指定用于口令验证的函数。请参见verify_password_function 选项 [数据库]

实现登录策略

使用登录策略控制用户口令更改的频率以及指定锁定帐户之前所允许的登录尝试次数。请参见管理登录策略概述CREATE LOGIN POLICY 语句

更改缺省用户 ID 和口令

新创建数据库的缺省用户 ID 为 DBA,口令为 sql。应在部署数据库之前更改此口令。

实现最低口令长度

缺省情况下,对口令的长度没有任何限制。要实现更高的安全性,可以对所有新口令规定最小长度要求,不允许使用短(因而容易被猜到的)口令。可通过将 min_password_length 数据库选项设置为一个大于零的值来实现此目的。下列语句强制口令至少为 8 字节长。

SET OPTION PUBLIC.min_password_length = 8;

请参见min_password_length 选项 [数据库]

实现口令到期功能

缺省情况下,数据库口令永远不到期。可以使用登录策略来实现口令到期功能。请参见管理登录策略概述

不要在 ODBC 数据源中包含口令

口令是用于访问数据库的密钥。在注重安全的环境中,口令不应被未经授权的人轻易地获取。

创建 ODBC 数据源或 Sybase Central 连接配置文件时,可以选择是否包括口令。请避免包括口令,以确保口令不会被未经授权的用户看到。

请参见创建 ODBC 数据源

对包含口令的配置文件进行加密

创建配置文件时,可以选择是否包括口令信息。为保护口令,可以考虑使用文件隐藏 (dbfhide) 实用程序通过简单加密来隐藏配置文件的内容。请参见文件隐藏实用程序 (dbfhide)

使用口令验证

可以使用 verify_password_function 选项来指定实现口令规则的函数。请参见verify_password_function 选项 [数据库]

以下示例定义表和函数并设置一些登录策略选项。它们共同实现了高级口令规则,其中包括要求在口令中使用某些类型的字符、不允许口令重用和为口令设置有效期。当创建用户 ID 或更改口令时,数据库服务器会通过 verify_password_function 选项调用函数。应用程序可以调用 post_login_procedure 选项指定的过程,以报告口令应在到期前进行更改。

也可以从以下位置获得此示例的代码:samples-dir\SQLAnywhere\SQL\verify_password.sql。(有关 samples-dir 的信息,请参见示例目录。)

-- This example defines a function that implements advanced password rules 
-- including requiring certain types of characters in the password and 
-- disallowing password reuse. The f_verify_pwd function is called by the 
-- server using the verify_password_function option when a user ID is 
-- created or a password is changed.  
--
-- The "root" login profile is configured to expire passwords every 180 days
-- and lock non-DBA accounts after 5 consecutive failed login attempts.
--
-- The application may call the procedure specified by the 
-- post_login_procedure option to report that the password should be changed 
-- before it expires.


-- only DBA should have permissions on this table
CREATE TABLE DBA.t_pwd_history(
        pk          INT         DEFAULT AUTOINCREMENT PRIMARY KEY,
        user_name   CHAR(128),          -- the user whose password is set
        pwd_hash    CHAR(32) );         -- hash of password value to detect
                                        -- duplicate passwords

-- called whenever a non-NULL password is set
-- to verify the password conforms to password rules
CREATE FUNCTION DBA.f_verify_pwd( uid     VARCHAR(128),
                                  new_pwd VARCHAR(255) )
RETURNS VARCHAR(255)
BEGIN
    -- a table with one row per character in new_pwd
    DECLARE local temporary table pwd_chars(
            pos INT PRIMARY KEY,    -- index of c in new_pwd
            c   CHAR( 1 CHAR ) );   -- character
    -- new_pwd with non-alpha characters removed
    DECLARE pwd_alpha_only      CHAR(255);
    DECLARE num_lower_chars     INT;

    -- enforce minimum length (can also be done with
    -- min_password_length option)
    IF length( new_pwd ) < 6 THEN
        RETURN 'password must be at least 6 characters long';
    END IF;

    -- break new_pwd into one row per character
    INSERT INTO pwd_chars SELECT row_num, substr( new_pwd, row_num, 1 )
                            FROM dbo.RowGenerator
                            WHERE row_num <= length( new_pwd );

    -- copy of new_pwd containing alpha-only characters
    SELECT list( c, '' ORDER BY pos ) INTO pwd_alpha_only
        FROM pwd_chars WHERE c BETWEEN 'a' AND 'z' OR c BETWEEN 'A' AND 'Z';

    -- number of lower case characters IN new_pwd
    SELECT count(*) INTO num_lower_chars
        FROM pwd_chars WHERE CAST( c AS BINARY ) BETWEEN 'a' AND 'z';

    -- enforce rules based on characters contained in new_pwd
    IF ( SELECT count(*) FROM pwd_chars WHERE c BETWEEN '0' AND '9' )
           < 1 THEN
        RETURN 'password must contain at least one numeric digit';
    ELSEIF length( pwd_alpha_only ) < 2 THEN
        RETURN 'password must contain at least two letters';
    ELSEIF num_lower_chars = 0
           OR length( pwd_alpha_only ) - num_lower_chars = 0 THEN
        RETURN 'password must contain both upper- and lowercase characters';
    END IF;

    -- not the same as any user name
    -- (this could be modified to check against a disallowed words table)
    IF EXISTS( SELECT * FROM SYS.SYSUSER
                    WHERE lower( user_name ) IN ( lower( pwd_alpha_only ),
                                                  lower( new_pwd ) ) ) THEN
        RETURN 'password or only alphabetic characters in password ' ||
               'must not match any user name';
    END IF;

    -- not the same as any previous password for this user
    IF EXISTS( SELECT * FROM t_pwd_history
                    WHERE user_name = uid
                      AND pwd_hash = hash( uid || new_pwd, 'md5' ) ) THEN
        RETURN 'previous passwords cannot be reused';
    END IF;

    -- save the new password
    INSERT INTO t_pwd_history( user_name, pwd_hash )
        VALUES( uid, hash( uid || new_pwd, 'md5' ) );

    RETURN( NULL );
END;

ALTER FUNCTION DBA.f_verify_pwd SET HIDDEN;
GRANT EXECUTE ON DBA.f_verify_pwd TO PUBLIC;
SET OPTION PUBLIC.verify_password_function = 'DBA.f_verify_pwd';


-- All passwords expire in 180 days.  Expired passwords can be changed
-- by the user using the NewPassword connection parameter.
ALTER LOGIN POLICY root password_life_time = 180;

-- If an application calls the procedure specified by the 
-- post_login_procedure option, then the procedure can be used to warn 
-- the user that their password is about to expire.  In particular, 
-- Interactive SQL and Sybase Central call the 
-- post_login_procedure system procedure.
ALTER LOGIN POLICY root password_grace_time = 30;

-- Five consecutive failed login attempts will result in a non-DBA 
-- user ID being locked.
ALTER LOGIN POLICY root max_failed_login_attempts = 5;