ORA-28860: Неустранимая ошибка SSL при использовании UTL_HTTP?

Вопрос:

Мы используем Oracle 11g (11.2.0.3.0), и при выполнении вызова UTL_HTTP получаем следующую ошибку:

EXCEPTION: ORA-28860: Fatal SSL error
EXCEPTION: ORA-06512: at "SYS.UTL_HTTP", line 1128
ORA-06512: at line 23

EXCEPTION: ORA-28860: Fatal SSL error

Это код, который мы используем:

DECLARE
url_chr             VARCHAR2(500);
user_id_chr         VARCHAR2(100);
password_chr        VARCHAR2(20);
wallet_path_chr     VARCHAR2(500);
wallet_pass_chr     VARCHAR2(20);

l_http_request      UTL_HTTP.REQ;
l_http_response     UTL_HTTP.RESP;
l_text              VARCHAR2(32767);
BEGIN
url_chr           := '*****';
user_id_chr       := '*****';
password_chr      := '*****';
wallet_pass_chr   := '*****';
wallet_path_chr   := 'file:/etc/ORACLE/WALLETS/astens/rtca/cer/';

UTL_HTTP.SET_DETAILED_EXCP_SUPPORT(TRUE);

UTL_HTTP.SET_WALLET(wallet_path_chr, wallet_pass_chr);

l_http_request  := UTL_HTTP.BEGIN_REQUEST(url_chr);
UTL_HTTP.SET_AUTHENTICATION(r => l_http_request, username => user_id_chr, PASSWORD => password_chr);
l_http_response := UTL_HTTP.GET_RESPONSE(l_http_request);

DBMS_OUTPUT.PUT_LINE ('STATUS_CODE : ' || l_http_response.STATUS_CODE);

BEGIN
LOOP
UTL_HTTP.READ_TEXT(l_http_response, l_text, 32766);
DBMS_OUTPUT.PUT_LINE (l_text);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(l_http_response);
END;
EXCEPTION
WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE('EXCEPTION: '||SQLERRM);
DBMS_OUTPUT.PUT_LINE('EXCEPTION: '||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);

DBMS_OUTPUT.PUT_LINE('EXCEPTION: '||UTL_HTTP.GET_DETAILED_SQLERRM);
UTL_HTTP.END_RESPONSE(l_http_response);
END;

Мы установили поставляемые сертификаты в Oracle Wallet, и мы используем тот же код для разных клиентов без проблем.

Любые идеи?

Ответ №1

Сайт, который вы вызываете, может препятствовать подключению через устаревший протокол SSLv3, и в то же время более новый алгоритм может не поддерживаться Oracle DB 11.2.0.3.

Есть эта известная ошибка, но она влияет на версии до 11.1, очевидно:

Пакет UTL_HTTP не работает с ORA-29273 ORA-28860 при использовании TLSv1 (Doc ID 727118.1)
https://support.oracle.com/epmos/faces/DocContentDisplay?_afrLoop=842518171804826&id=727118.1&_afrWindowMode=0&_adf.ctrl-state=142oqbz21t_4

В последнее время также зарегистрирована ошибка 20323753, зарегистрированная для 11.2.0.4, но не исправлена. Возможно, это может быть тот же случай, что и ваш.

Ответ №2

Вы не указываете свои сетевые списки управления доступом к сети (ACL), но в Oracle 11g вы должны настроить ACL для хоста, к которому хотите подключиться, и для кошелька, который вы хотите использовать. Поскольку вы не упоминаете об ошибке “ORA-24247: отказ в доступе к сети через контроль доступа (ACL)”, я предположим, что эта часть настроена правильно.

ACL кошелька определяет его местоположение и предоставляет привилегии против кошелька пользователям. Без этих привилегий Oracle не откроет кошелек и не предоставит сертификат веб-серверу, даже если у вас есть правильный пароль. ACL кошелька создается со следующим запуском PL/SQL как SYS:

BEGIN
UTL_HTTP.ASSIGN_WALLET_ACL (
acl          => 'your_acl_name.xdb',
wallet_path  => '/path/to/my/wallet/');
END;
/

После создания ACL кошелька пользователь должен иметь предоставленные ему привилегии.

BEGIN
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
acl         => 'your_acl_name.xml',
principal   => 'MY_USER',
is_grant    =>  TRUE,
privilege   => 'use-client-certificates');
END;
/

Это позволит Oracle открыть кошелек от имени вашего пользователя и представить сертификат на веб-сервер.

Ответ №3

Я хотел бы предложить следующее:

  • Создайте JAVA-функцию

    CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "HttpSSLGet"
    AS
    import java.net.URL;
    import java.io.*;
    import javax.net.ssl.HttpsURLConnection;
    public class HttpSSLGet
    {
    public static String GetSSL(final String url)
    {
    StringBuffer buffer = new StringBuffer();
    try
    {
    URL myUrl = new URL(url);
    HttpsURLConnection con = (HttpsURLConnection)myUrl.openConnection();
    InputStream ins = con.getInputStream();
    InputStreamReader isr = new InputStreamReader(ins);
    BufferedReader in = new BufferedReader(isr);
    String inputLine;
    
    while ((inputLine = in.readLine()) != null)
    {
    buffer.append(inputLine);
    }
    in.close();
    }
    catch (Exception e)
    {
    return buffer.toString() + "\n" + e.toString();
    }
    return buffer.toString();
    }
    }
    
  • Создайте пакет PL/SQL (автономной функции)

    CREATE OR REPLACE PACKAGE PCK_HTTP AUTHID DEFINER
    AS
    
    function GetSSL(aUrl Varchar2) return Varchar2;
    
    END;
    /
    
    CREATE OR REPLACE PACKAGE BODY PCK_HTTP AS
    
    function GetSSL(aUrl Varchar2) return Varchar2 AS LANGUAGE JAVA
    NAME 'HttpSSLGet.GetSSL(java.lang.String) return java.lang.String';
    
    END;
    /
    
  • В Oracle существует проблема со встроенной JAVA-машиной. Он содержит меньше сертификатов в качестве стандартного “сатанталона” JAVA. Вероятно, вы должны добавить загруженный сертификат в встроенную java-машину (не автономную java), например. в командной строке (Windows):

    keytool -import -alias geos -keystore
    "d:\Oracle\product\11.2.0\dbhome_1\javavm\lib\security\cacerts"
    -file example.com.cer -storepass changeit
    
  • Используйте функцию в запросе или PL/SQL, например,

    SELECT PCK_HTTP.GetSSL('https://www.example.com') FROM DUAL
    
Ответ №4

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

Оцените статью
TechArks.Ru
Добавить комментарий