В процессе переезда на Oracle Database 19c одной из задач возник вопрос - а как перевезти пользователя с Oracle 9 на Oracle 19c с сохранением пароля? Квест оказался ещё тот. Запрос в Oracle Support дал немного - нужно было использовать старый добрый exp. Попутно возник вопрос - а можно ли перенести пользователя с текущим паролем? Обсуждение на sql.ru показало, что таким путём придётся идти самому, немногие в 2021 году переходят с 9i на 19c.

Oracle Support подсказал следующие документы:

  • Oracle Password Management Policy (Doc ID 114930.1)
  • User Passwords Are No Longer Visible In DBA_USERS As Of 11g (Doc ID 735651.1)

На sql.ru коллега дал ссылку на интересную статью на исследование Sean D. Stuber функции хэширования, используемой Oracle. Мой перевод статьи следует.

How Oracle Stores Passwords Sean D. Stuber

Аннотация Администратору баз данных может потребоваться репликация пользователя из одной системы в другую, сохраняя пароль, или восстановить пароль после обновления системы. В старых системах (8.0.5 и ранее), чтобы временно разрешить пользователю входить в систему под другим именем, администратору базы данных или другому привилегированному пользователю потребуется изменить пароль. До 9i даже администратор баз данных не мог предоставлять разрешения на объекты схемы, не войдя в систему как владелец схемы. Поэтому нередко обнаруживалась необходимость сохранять пароли, временно изменять их для входа в систему, а затем восстанавливать старую версию, когда работа была завершена. С появлением прокси-пользователей (8i) и GRANT ANY OBJECT PRIVILEGE (9i) необходимость в выполнении этих шагов была в значительной степени устранена; но администраторам по-прежнему полезно понимать, где и как Oracle хранит пароли пользователей.

Original publication:  2009-06-09
Updated through Oracle 19c:  2019-12-20

I. АУТЕНТИФИКАЦИЯ

Имя пользователя хранится в виде обычного текста, а информация о пароле хранится в виде хеша. Когда пользователь входит в систему, аутентификационная информация хешируется в соответствии с правилами версии пароля. Если сгенерированный хеш и сохраненный хеш совпадают, пользователь аутентифицируется.

Возникает очевидный вопрос: почему Oracle использует хеширование вместо шифрования? Хеширование не является обратимой операцией; но шифрование есть. Последствия этого просты. Поскольку вы не можете перевернуть хеш, вы не можете извлечь пароль из хеша; но, если пароль зашифрован, он может быть незашифрованным (хотя и с трудом, но все же возможно). Теоретически чрезвычайно удачная догадка случайных символов или перебор всех возможных комбинаций может пройти с ложноположительным результатом, поскольку хеш-алгоритмы можно дублировать. Однако простейший алгоритм Oracle дает 18 446 744 073 709 551 616 возможных хэшей. Таким образом, хотя возможно, что две разные строки могут иметь одно и то же значение, вероятность найти одну мала.

II. Алгоритм хеширования и стойкость для 10G и ниже

А. Стойкость Для версий базы данных до 11g пароли хранятся в виде 16-значного шестнадцатеричного числа в столбце PASSWORD таблицы SYS.USER $. Хэш публикуется из базовой таблицы USER $ через представление SYS.DBA_USERS.

SQL> connect dbauser/dbapassword@mydatabase
Connected.
SQL> select username,password from dba_users where username = 'TESTUSER';

USERNAME   PASSWORD
---------- ------------------
TESTUSER   AEB6397C8E7598A7

SQL> select name,password from sys.user$ where name = 'TESTUSER';

NAME       PASSWORD
---------- ------------------------
TESTUSER   AEB6397C8E7598A7


Б. Алгоритм
Хеширование - это многоэтапный процесс. Сначала имя пользователя и пароль объединяются в одну строку, которая переводится в верхний регистр. Затем эта строка преобразуется в многобайтовое необработанное значение с ведущими нулями для каждого байта. Это необработанное значение затем шифруется стандартным алгоритмом DES с использованием ключа по умолчанию. Последние 16 байтов вывода затем используются в качестве нового ключа для второго шифрования необработанного значения. Последние 16 байтов второго шифрования становятся хранимым хеш-значением имени пользователя и пароля. 


В методологии есть несколько заметных недостатков. Во-первых, конкатенация не имеет внешней соли, поэтому пользователи с идентичными именами и паролями, за исключением смещения символов, могут стать одинаковыми при объединении. Например: Пользователь ABCD с паролем EFGH будет объединен в форму: ABCDEFGH. Другой пользователь ABC с паролем DEFGH будет объединен, чтобы сформировать ту же строку: ABCDEFGH. Это открывает (хотя и с чрезмерным потреблением ресурсов) вектор атаки. Кроме того, алгоритм DES устарел по сравнению с современными стандартами шифрования и, как таковой, подвержен вычислительным атакам с достаточными ресурсами, особенно когда атака связана с радужными таблицами. Что еще более важно, принудительное использование верхнего регистра для начальной конкатенации означает, что этот алгоритм не может поддерживать пароли с учетом регистра.

C. Код
Приведенный ниже код не является реальной функцией, которую использует Oracle; но он имитирует функциональность Oracle. При вводе имени пользователя и пароля функция вернет то же значение, которое Oracle генерирует и сохраняет в столбце SYS.USER $ .PASSWORD.

CREATE OR REPLACE FUNCTION create_10g_password_hash(p_name IN VARCHAR2,
                                                    p_password IN VARCHAR2)
    RETURN VARCHAR2
IS
    c_raw_zero            RAW(1) := HEXTORAW('0');
    c_encryption_method   INTEGER := 
                 DBMS_CRYPTO.encrypt_des + DBMS_CRYPTO.chain_cbc + DBMS_CRYPTO.pad_zero;
    v_str                 VARCHAR2(100);
    v_raw                 RAW(4096) := NULL;
    v_default_key         RAW(15) := HEXTORAW('0123456789ABCDEF');
    v_new_key             RAW(4096);
    v_encrypted           RAW(4096);
BEGIN
    -- Concatenate the username and password
    v_str := UPPER(p_name || p_password);

    -- Convert plain ascii string to multi-byte string with 0x00 in the high byte
    FOR i IN 1 .. LENGTH(v_str)
    LOOP
        v_raw := UTL_RAW.CONCAT(v_raw, c_raw_zero, 
                                UTL_RAW.cast_to_raw(SUBSTR(v_str, i, 1)));
    END LOOP;

    -- Encrypt with DES chipher block chaining (cbc) using default key
    -- Pad with 0's to the next even block length
    v_encrypted := DBMS_CRYPTO.encrypt(v_raw, c_encryption_method, v_default_key);

    -- Use the last 16 digits of the default encryption to generate a new key
    v_new_key := HEXTORAW(SUBSTR(RAWTOHEX(v_encrypted), -16));

    -- Re-encrypt with the new key
    v_encrypted := DBMS_CRYPTO.encrypt(v_raw, c_encryption_method, v_new_key);

    -- The last 16 digits are the hash
    RETURN SUBSTR(RAWTOHEX(v_encrypted), -16);
END create_10g_password_hash;

III. АЛГОРИТМ ХЕШИРОВАНИЯ И УСТОЙЧИВОСТЬ ДЛЯ 11G

А. Стойкость

В 11g добавлен новый алгоритм хеширования, и с этим изменением сохраненный хэш перемещен из столбца PASSWORD в USER $ в столбец SPARE4. Хэш 10g, если он все еще используется, сохраняется в старом столбце PASSWORD, как и раньше. Ни один из этих хэшей не публикуется через представление DBA_USERS. Вместо этого столбец PASSWORD представления возвращает NULL, а новый столбец PASSWORD_VERSIONS указывает, какие типы хэшей пароля хранятся.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME   PASSWORD             PASSWORD_VERSIONS                                                                                                     
---------- -------------------- --------------------                                                                                                  
TESTUSER                        10G 11G                                                                                                               

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';

NAME       PASSWORD             SPARE4                                                                                                                
---------- -------------------- ---------------------------------------------------------------                                                       
TESTUSER   AEB6397C8E7598A7     S:17F9149EFD0BDD9DBA305D6910D5928640F7727B29F261D851C58D37FA9A

Б. Алгоритм

В 11g алгоритм хеширования улучшен двумя способами. Во-первых, используется более современный алгоритм хеширования (SHA-1) вместо получения хеша из подстрок зашифрованного вывода. Во-вторых, вместо имени пользователя в качестве соли используется рандомизированная соль. Эти изменения позволяют поддерживать чувствительность к регистру в именах пользователей и паролях.

Хотя алгоритм более надежен, он также упрощен за счет этих изменений. Сначала с помощью рандомизатора генерируется 10-байтовое (20 шестнадцатеричных цифр) значение соли. Затем это значение присоединяется к необработанной версии пароля. Это необработанное значение затем хешируется с помощью алгоритма SHA-1. Результат представлен в виде шестнадцатеричной строки с префиксом «S:» и суффиксом с шестнадцатеричным представлением соли.

Таким образом, в приведенном выше примере запись spare4 может быть разделена на части:
Это хеш пароля: 17F9149EFD0BDD9DBA305D6910D5928640F7727B
Это соль: 29F261D851C58D37FA9A

К сожалению, хотя алгоритм хеширования 11g более безопасен, чем его более старая версия, к тому времени, когда 11g был впервые выпущен в 2007 году, коллизионные атаки на SHA-1 уже были продемонстрированы двумя годами ранее.

C. Код

Приведенный ниже код имитирует функцию хеширования Oracle 11g. Ввод пароля и значения соли вернет то же значение, которое Oracle генерирует и сохраняет в столбце SYS.USER $ .SPARE4.

CREATE OR REPLACE FUNCTION create_11g_password_hash(p_password IN VARCHAR2, 
                                                    p_hex_salt IN VARCHAR2)
    RETURN VARCHAR2
IS
    v_hash   RAW(80);
BEGIN
    -- The salt can be any value that is exactly 10 bytes (80 bits)
    -- i.e. the input salt must be 20 hex characters.
    IF NVL(LENGTH(p_hex_salt),0) != 20
    THEN
        raise_application_error(-20001, 'Salt must be 20 hex digits (0-9,A-F');
    END IF;

    -- Concatenate the password with the salt
    v_hash := UTL_RAW.CONCAT(UTL_RAW.cast_to_raw(p_password), HEXTORAW(p_hex_salt));

    -- Hash the concatenation
    v_hash := sys.DBMS_CRYPTO.hash(v_hash, sys.DBMS_CRYPTO.hash_sh1);

    -- Append the salt to the resulting hash and tag with "S:" prefix
    RETURN 'S:' || RAWTOHEX(v_hash) || p_hex_salt;
END create_11g_password_hash;

D. Использование 12c

Первоначальный выпуск 12c (версия 12.1.0.1) также использовал алгоритм хеширования 11g. Первый набор исправлений для 12c, 12.1.0.2, представил более новый и более безопасный алгоритм.

IV. АЛГОРИТМ ХЕШИРОВАНИЯ И УСТОЙЧИВОСТЬ ДЛЯ 12C (12.1.0.2 И ВЫШЕ)

А. Стойкость

Использование столбца SPARE4 расширено в 12.1.0.2 за счет включения хэша 12c, а также хэша 11g. Различные хэши обозначаются их префиксами (S для 11g, T для 12c) и разделяются точкой с запятой. Другой тип хэша, для XDB, также может быть включен (с префиксом «H»), но он не связан с входами обычного пользователя и как таковой выходит за рамки данной статьи. В столбце PASSWORD все еще хранятся старые хэши паролей 10g; но ни одна из версий не отображается в представлении DBA_USERS. 18c использует те же алгоритмы и конфигурацию. Сложность алгоритма хеширования 12c приводит к значительно большей хэш-строке: 160 символов, как показано ниже. Из-за длины хэш-строк приведенный ниже код будет извлекать каждую из них по отдельности, а не все в одной строке запроса.

SQL> SELECT username, password, password_versions
  2    FROM dba_users
  3   WHERE username = 'TESTUSER';

USERNAME   PASSWORD   PASSWORD_VERSIONS
---------- ---------- ---------------------
TESTUSER              10G 11G 12C

SQL> SELECT password pwd_10g
  2    FROM sys.user$
  3   WHERE name = 'TESTUSER';

PWD_10G
----------------
AEB6397C8E7598A7

SQL> SELECT REGEXP_SUBSTR(spare4, 'S:[^;]+') pwd_11g
  2    FROM sys.user$
  3   WHERE name = 'TESTUSER';

PWD_11G
--------------------------------------------------------------
S:7233E3B91B45F6B813BCFFB5D8669167CB4F498D0642558A8A3BB39948C0

SQL> SELECT REGEXP_SUBSTR(spare4, 'T:[^;]+') pwd_12c
  2    FROM sys.user$
  3   WHERE name = 'TESTUSER';

PWD_12C
------------------------------------------------------------------------------------------------------------------------------------------------------------------
T:381A70048CBB5B531196CDD2CB51393E05E3FBFB0CB019DB39AB4AAB717BB23CA7FB2EA0AD4F60B34C38C9B8CF97BB0C6A4A7530362FBF23492FB02139442AB758645C9EA1D1E33C33CB9454D0468BF9

Б. Алгоритм

Алгоритм хеширования 12c имеет несколько улучшений. Во-первых, само хеширование повторяется 4096 раз в соответствии со спецификацией PBKDF2 с SHA-512 в качестве функции HMAC для получения окончательного ключа. Подобно исходному алгоритму 10g и ниже, по умолчанию используется ключ хеширования или соль. Однако, в отличие от более старой версии, значение по умолчанию составляет только часть полной соли, остаток поступает из 128-битного входного параметра соли (представлен 32 шестнадцатеричными цифрами). В базе данных нет встроенной функции PBKDF2, так что реализация ниже включает его версию. Некоторые параметры, описанные в RFC2898, объявлены в этой версии как константы, поскольку их использование не меняется в пределах правил хеширования паролей.

Как только ключ PBKDF2 получен, пароль и производный ключ затем снова хешируются с использованием пользовательской соли с помощью метода SHA-512. Наконец, как и в случае с методом 11g, к этому хешу добавляется пользовательская соль, а затем записывается в столбец SYS.USER $ .SPARE4. Префикс «T» используется для отличия хэшей 12.1.0.2 от хэшей 11g с префиксом «S». Затем хэши 12C идентифицируются в столбце PASSWORD_VERSIONS представления DBA_USERS.

Таким образом, в приведенном выше примере запись spare4 может быть разделена на части:
Это хэш пароля 11g: 7233E3B91B45F6B813BCFFB5D8669167CB4F498D
Это соль размером 11 г: 0642558A8A3BB39948C0
Это хеш пароля 12c: 
381A70048CBB5B531196CDD2CB51393E05E3FBFB0CB019DB39AB4AAB717BB23CA7FB2EA0AD4F60B34C38C9B8CF97BB0C6A4A7530362FBF23492FB02139442AB758645C9EA1D1E33C33CB9454D0468BF9
Это соль 12c: 58645C9EA1D1E33C33CB9454D0468BF9

 Б. Назначение нескольких версий

Приведенный выше синтаксис назначения подходит для пользователей с одним типом хэша пароля; но если у пользователя PASSWORD_VERSIONS несколько значений, неназначенные значения будут удалены. Чтобы назначить несколько версий хеша одновременно, хеши должны быть объединены в одну строку; через точку с запятой (;). Порядок хешей не имеет значения. База данных разделит хэш 10g на столбец SYS.USER $ .PASSWORD и расположит хеш 11g перед хешем 12c в столбце SPARE4, если оба присутствуют. Если используется, упомянутый ранее хеш XDB также может быть включен в составную строку.

В приведенном ниже примере с несколькими хешами пароли объединены в следующем порядке: «12c; 10g; XDB; 11g», но их можно изменить в любом порядке. Опять же, в строке хеша не должно быть разрывов строки. Обтекание текстом связано с ограничениями ширины страницы.

381A70048CBB5B531196CDD2CB51393E05E3FBFB0CB019DB39AB4AAB717BB23CA7FB2EA0AD4F60B34C38C9B8CF97BB0C6A4A7530362FBF23492FB02139442AB758645C9EA1D1E33C33CB9454D0468BF9

VI. ЧУВСТВИТЕЛЬНОСТЬ К РЕГИСТРУ

Как отмечалось выше, хеширование 10g не поддерживает пароли с учетом регистра; но в 11g новый алгоритм может их поддерживать, если в базе данных включена эта функция. Чувствительность к регистру включается и выключается системным параметром sec_case_sensitive_logon. Если TRUE, пароли будут поддерживать чувствительность к регистру (с использованием хеширования 11g / 12c), если FALSE, то нет. Значение по умолчанию TRUE. Начиная с версии 12.1, этот параметр устарел, но все еще поддерживается.

SQL> show parameters sec_case;

NAME                                 TYPE        VALUE                                                                                                
------------------------------------ ----------- ------------------------------                                                                       
sec_case_sensitive_logon             boolean     TRUE   
                                                                                              
SQL> alter user testuser identified by testpwd;

User altered.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME   PASSWORD             PASSWORD_VERSIONS                                                                                                     
---------- -------------------- --------------------                                                                                                  
TESTUSER                        10G 11G                                                                                                               

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';


NAME       PASSWORD         SPARE4                                                                                                                
---------- ---------------- ------------------------------------------------------------                                       
TESTUSER   AEB6397C8E7598A  S:17F9149EFD0BDD9DBA305D6910D5928640F7727B29F261D851C58D37FA9A                                                        

SQL> connect testuser/testpwd;
Connected.

В следующем примере для учетной записи TESTUSER изменен пароль с «testpwd» на «TestPwd». И мы используем условие, определяемое значениями, чтобы гарантировать, что у нас есть только 10g хэш. Сначала мы проверяем статус параметра, затем меняем пароль и проверяем логин пользователя. Затем убедитесь, что пароль смешанного регистра соблюдается на основе настройки V $ PARAMETER, показанной выше.

SQL> alter user testuser identified by values 'AEB6397C8E7598A7';

User altered.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME   PASSWORD             PASSWORD_VERSIONS                                                                                                     
---------- -------------------- --------------------                                                                                                  
TESTUSER                        10G                                                                                                                   

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';

NAME       PASSWORD             SPARE4                                                                                                                
---------- -------------------- ---------------------------------------------------------------                                                       
TESTUSER   AEB6397C8E7598A7                                                                                                                           

SQL> connect testuser/testpwd;
Connected.
SQL> connect testuser/TestPwd;
Connected.
SQL> connect dbauser/dbapassword;
Connected.
SQL> alter user testuser identified by values 'S:C7C0B0D97F60CA87C0CEB1663522C76509BD2FF84624774EAED94982A453';

User altered.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME   PASSWORD             PASSWORD_VERSIONS                                                                                                     
---------- -------------------- --------------------                                                                                                  
TESTUSER                        11G                                                                                                                   

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';

NAME       PASSWORD             SPARE4                                                                                                                
---------- -------------------- ---------------------------------------------------------------                                                       
TESTUSER                        S:C7C0B0D97F60CA87C0CEB1663522C76509BD2FF84624774EAED94982A453                                                        

SQL> connect testuser/testpwd;
ERROR:
ORA-01017: invalid username/password; logon denied 


Warning: You are no longer connected to ORACLE.
SQL> connect testuser/TestPwd;
Connected.

В следующем примере пароль будет изменен со строчного на смешанный. Обратите внимание, что хэш 10g в поле PASSWORD в USER $ не изменится; но хеш SPARE4 изменится. Таким образом, хотя хэш 10g сохраняется, он недействителен для использования, пока включена чувствительность к регистру и действуют хешированные пароли 11g. Однако, если хэш 10g является единственным доступным хешем, то параметр sec_case_sensitive_logon не применяется к этому пользователю. После подтверждения правильного соблюдения чувствительности к регистру, хеш 11g удаляется, остается только хеш 10g. Учитывать регистр по-прежнему; но пользователь может войти в систему с разными регистрами.

SQL> connect dbauser/dbapassword
Connected.
SQL> alter user testuser identified by testpwd;

User altered.

SQL> select password,spare4 from sys.user$ where name = 'TESTUSER';

PASSWORD                       SPARE4
------------------------------ --------------------------------------------------------------
AEB6397C8E7598A7               S:34391551DB0AADE86B6A1A7263B8F217C8B65FF66E4829BA7AA0B846653E

SQL> alter user testuser identified by TestPwd;

User altered.

SQL> select password,spare4 from sys.user$ where name = 'TESTUSER';

PASSWORD                       SPARE4
------------------------------ --------------------------------------------------------------
AEB6397C8E7598A7               S:777A9BE09BBAF3C7D3AD7D964471C15B948FB710870627D38B84EA9668EF

SQL> connect testuser/testpwd
ERROR:
ORA-01017: invalid username/password; logon denied

Warning: You are no longer connected to ORACLE.
SQL> connect testuser/TestPwd
Connected.
SQL> connect dbauser/dbapassword
Connected.
SQL> alter user testuser identified by values 'AEB6397C8E7598A7';

User altered.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME                       PASSWORD                       PASSWORD
------------------------------ ------------------------------ --------
TESTUSER                                                      10G

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';

NAME               PASSWORD                       SPARE4
------------------ ------------------------------ -----------------------------------
TESTUSER           AEB6397C8E7598A7

SQL> show parameters sec_case;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sec_case_sensitive_logon             boolean     TRUE
SQL> connect testuser/testpwd
Connected.
SQL> connect testuser/TestPwd
Connected.

Интересная особенность безопасности возникает, если отключена чувствительность к регистру, когда нет хэша 10g. Если это произойдет, то пользователь будет заблокирован, потому что хеш 10g является единственным хешем, используемым (или может использоваться) для паролей без учета регистра. В приведенном ниже примере тестовый пользователь все еще имеет пароль «TestPwd», как указано выше, но не сможет войти в систему, потому что чувствительность к регистру отключена.

SQL> connect dbauser/dbapassword
Connected.
SQL> alter user testuser identified by values 'S:C7C0B0D97F60CA87C0CEB1663522C76509BD2FF84624774EAED94982A453';

User altered.

SQL> select username,password,password_versions from dba_users where username = 'TESTUSER';

USERNAME                       PASSWORD                       PASSWORD
------------------------------ ------------------------------ --------
TESTUSER                                                      11G

SQL> select name,password,spare4 from sys.user$ where name = 'TESTUSER';

NAME            PASSWORD               SPARE4
--------------- ---------------------- --------------------------------------------------------------
TESTUSER                               S:C7C0B0D97F60CA87C0CEB1663522C76509BD2FF84624774EAED94982A453

SQL> alter system set sec_case_sensitive_logon=FALSE;

System altered.

SQL> show parameters sec_case;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
sec_case_sensitive_logon             boolean     FALSE
SQL> connect testuser/testpwd
ERROR:
ORA-01017: invalid username/password; logon denied


Warning: You are no longer connected to ORACLE.
SQL> connect testuser/TestPwd
ERROR:
ORA-01017: invalid username/password; logon denied

VII. ПРАВИЛА ВЕРСИИ ПАРОЛЯ SQLNET.ORA

В 11gR1 файл SQLNET.ORA получил новый * параметр: SQLNET.ALLOWED_LOGON_VERSION. Хотя этот параметр не влиял напрямую на хеширование паролей; это может создать несовместимость управления версиями, в результате чего пользователь с действующим паролем не сможет войти в систему. То есть, если параметр был установлен на 10 или 11, то можно использовать только 10 г хэшей пароля без применения критического обновления для клиента. С ЦП можно использовать хэши 10 г или 11 г. Если для параметра установлено значение 12, то будет работать только хэш 11g, поскольку поддерживается только протокол 11g.

12cR1 расширил эту функциональность, разделив параметр на два: SQLNET.ALLOWED_LOGON_VERSION_CLIENT и SQLNET.ALLOWED_LOGON_VERSION_SERVER. Параметр «client» определяет, какие протоколы поддерживаются при подключении в качестве клиента. Параметр «сервер» определяет, какие протоколы поддерживаются при получении соединений в качестве сервера. В обоих случаях управление версиями будет влиять на то, какие версии хеширования будут использоваться при аутентификации. 10 или ниже будет поддерживать любой из 3 алгоритмов хеширования паролей. 11 будет поддерживать только хеши 11g и 12c. Установка параметра на 12 может немного ввести в заблуждение, потому что это приведет к принудительному использованию клиентов 12c, но по-прежнему разрешит хэши 11g. Чтобы принудительно использовать хеширование 12c, параметр должен быть установлен в 12a.

Как отмечалось ранее, начиная с 12cR1, параметр базы данных sec_case_sensitive_logon не рекомендуется в пользу использования параметров SQLNET.ORA для управления поддерживаемыми алгоритмами хеширования.

* В 10gR1 Oracle представила параметр SQLNET_ALLOWED_LOGON_VERSION, который позже был заменен на SQLNET.ALLOWED_LOGON_VERSIONS. Однако, поскольку был доступен только один алгоритм хеширования паролей, этот параметр не имел никакого отношения к использованию хеширования паролей.

VIII. СПЕЦИАЛЬНЫЕ ФОРМАТЫ

У некоторых пользователей вообще нет хэша, вместо этого они хранятся с фиксированными значениями.

ANONYMOUS  - SYS.USER$.PASSWORD имеет значение ровно 16 пробелов. Столбец SPARE4 имеет значение NULL. Поскольку значение не является результатом хеширования, невозможно войти в систему с пользователем напрямую, так как пароль не будет хешировать это значение. При чтении из представления DBA_USERS значение PASSWORD_VERSIONS равно NULL. Можно создать такого собственного пользователя, используя предложение IDENTIFIED BY VALUES ровно из 16 пробелов; но это не особенно полезно. Возможно, в версиях до 18 db его можно было использовать для создания учетной записи только для схемы, поскольку ее нельзя было использовать для входа в систему.

XS$NULL - этот аккаунт не является настоящим пользователем. Согласно документации Oracle, это «внутренняя учетная запись, которая представляет отсутствие пользователя в сеансе». Значение SYS.USER$.PASSWORD равно NULL. Значение SPARE4 представляет собой заполнитель размером 11g «S:», за которым следуют 60 пробелов.

18c представил новый тип пользователя, названный пользователем «только схема». Это означает, что у него нет прямого входа. Намерение состоит в том, что эти учетные записи будут владеть объектами. Их нельзя использовать для входа пользователей или приложений в систему, что обеспечивает дополнительный уровень изоляции и безопасности. Значение SYS.USER$ .PASSWORD равно NULL, значение SPARE4 содержит хеш-метки 11g и 12c, состоящие только из нулей и соли. Таким образом, за «S:» следует 40 нулей и 20 шестнадцатеричных символов для соли. Затем «T:», за которым следует 128 нулей и 32-значная шестнадцатеричная соль.

Опция Multi-Tenant также вводит специальные форматы паролей. В пределах CDB$ROOT обычные пользователи будут следовать стандартным правилам хеширования и хранения. Однако при просмотре из подключаемых баз данных обычные пользователи будут иметь значение NULL для SYS.USER$.PASSWORD. Значение SPARE4 будет иметь заполнители «S:» и «T:», но значения будут полностью состоять из пробелов - 60 пробелов для значения 11g и 160 пробелов для значения 12c.

IX. НАСТРОЙКА

Как указано выше, эта статья не является руководством по взлому учетных записей пользователей Oracle. Демонстрации показывают изменение пароля пользователя. Однако эти изменения предполагают, что пользователь DBA существует с необходимыми привилегиями, уже предоставленными законными способами. Следующие команды, если они выполняются SYS, создадут такого пользователя; а также соответствующий тестовый пользователь, использованный в приведенных выше примерах.

X. ПРЕДОСТЕРЕЖЕНИЯ

Хотя администратор баз данных может иметь возможность или даже право изменять пароль пользователя, это не означает, что он или она должны это делать, поскольку могут возникнуть нежелательные последствия.

  • Если у пользователя есть профиль, который не позволяет повторно использовать пароль, администратору базы данных может быть запрещено восстанавливать старый пароль после его изменения. Администратор базы данных может иметь право изменять профили, чтобы разрешить это, или изменять пользователя на другой профиль, а затем восстанавливать профиль.
  • Если срок действия пароля пользователя истекает, сброс значения хеш-функции приведет к сбросу счетчика. Таким образом, позволяя этому паролю оставаться дольше, чем это обычно допускается.
  • Если исходный хеш потерян, опечатан, вставлен неправильно или иным образом поврежден, то этот пользователь не сможет войти в систему, пока не будет создан новый пароль.
  • И последнее и самое очевидное: выполнение описанных выше шагов позволяет администратору баз данных выдавать себя за другого пользователя. Это может нарушить политику безопасности / этики компании. Надлежащий аудит и авторизация могут решить эти проблемы.

ИСТОЧНИКИ

  1. Oracle 18c Database SQL Language Reference https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/index.html 
  2. Database PL/SQL Packages and Types Reference https://docs.oracle.com/en/database/oracle/oracle-database/18/arpls/index.html 
  3. Xiaoyun Wang, Yiqun Lisa Yin, Hongbo Yu, (2005, February 13) “Collision Search Attacks on SHA1” http://courses.csail.mit.edu/6.885/spring05/papers/wangyinyu.pdf 
  4. Martin Rakhmanov, (2015, June 1) Changes in Oracle Database 12c password hashes https://www.trustwave.com/Resources/SpiderLabs-Blog/Changes-in-Oracle-Database-12c-password-hashes
  5. RSA Laboratories, (2000, September) Password-Based Cryptography Specification https://tools.ietf.org/html/rfc2898

Об авторе

Шон Д. Стубер - администратор баз данных и разработчик с более чем 25-летним опытом работы, большая часть из которых работает с базами данных Oracle. В его основные обязанности входит кодирование, настройка и обучение других разработчиков тому, как наилучшим образом использовать свои базы данных Oracle. Он неоднократно выступал на конференции Collaborate для IOUG, а также на конференции KScope для ODTUG. Он является тематическим советником и регулярно отвечает на вопросы по Oracle и базам данных на сайте Experts-Exchange (www.experts-exchange.com). С Шоном можно связаться по адресу Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в вашем браузере должен быть включен Javascript. 

PDF-файл этой статьи можно загрузить из моего Dropbox здесь.

 

1 1 1 1 1 1 1 1 1 1 Rating 0.00 (0 Votes)