Вопрос:
Мы используем 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:Oracleproduct11.2.0dbhome_1javavmlibsecuritycacerts» -file example.com.cer -storepass changeit
-
Используйте функцию в запросе или PL/SQL, например,
SELECT PCK_HTTP.GetSSL(‘https://www.example.com’) FROM DUAL
Ответ №4
Мы обнаружили, что старые сертификаты в кошельке для сайта https, хотя срок их действия не истек, больше не могут быть использованы. Тест с новыми сертификатами в новом кошельке доказал это. Удаление старого сертификата и добавление новых сертификатов в оригинальный кошелек решило проблему.