我们正在使用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中,我们对不同的客户端使用相同的代码而没有问题。
有什么想法吗?
答案 0 :(得分:4)
您正在调用的站点可能会阻止通过过时的SSLv3协议进行连接,同时Oracle DB 11.2.0.3可能不支持更新的算法。
有这个已知错误,但它显然影响了11.1版本:
使用TLSv1时,UTL_HTTP程序包因ORA-29273 ORA-28860失败(文档ID 727118.1) https://support.oracle.com/epmos/faces/DocContentDisplay?_afrLoop=842518171804826&id=727118.1&_afrWindowMode=0&_adf.ctrl-state=142oqbz21t_4
最近还有一个针对11.2.0.4注册的错误20323753,仍然没有修复。可能与你的情况相同。
答案 1 :(得分:2)
您没有提及您的网络访问控制列表(ACL)授权,但在Oracle 11g中,您必须为要连接的主机和要使用的钱包设置ACL。由于您没有提到“ORA-24247:访问控制列表(ACL)拒绝网络访问”错误,我将假设该部分已正确设置。
钱包ACL定义其位置并向用户授予针对钱包的权限。如果没有这些权限,即使您拥有正确的密码,Oracle也不会打开钱包并将证书提供给Web服务器。钱包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代表您的用户打开钱包并将证书提供给Web服务器。
答案 2 :(得分:0)
我想提供以下内容:
创建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机器存在问题。它包含较少的证书作为标准的“satandalone”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
答案 3 :(得分:0)
我们发现https站点的钱包中的旧证书即使未过期也不再可用。用新钱包中的新证书进行测试证明了这一点。删除旧证书并将新证书添加到原始钱包即可解决此问题。