簡體   English   中英

PL/SQL 中的 Oracle DBMS_LDAP.open_ssl 顯示錯誤:ORA-31202:SSL 握手失敗

[英]Oracle DBMS_LDAP.open_ssl in PL/SQL shows error: ORA-31202: SSL handshake failed

我們已經切換到新的 Microsoft ADFS 服務器,現在我們必須使用 LDAPS(端口 636 上的 LDAP over SSL)。 但是在 PL/SQL 包中通過添加 DBMS_LDAP.open_ssl(基於這里)我得到:

ORA-31202: DBMS_LDAP: LDAP client/server error: SSL handshake failed

我的故障排除指導我對連接進行 tcpdump 調試,我發現 Oracle (12.1.0.2) DBMS_LDAP 在 SSL 握手時僅使用以下三個密碼套件,這些套件都非常舊且不安全,並且不受最新的 Microsoft AD 支持。 甚至我用 ldap.google.com:636 嘗試了另一個 12c db (12.1.0.2.0) 並收到相同的錯誤和相同的密碼套件。

Version: TLS 1.2 (0x0303)
Cipher Suite: TLS_DH_anon_WITH_3DES_EDE_CBC_SHA (0x001b)
Cipher Suite: TLS_DH_anon_WITH_RC4_128_MD5 (0x0018)
Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

Oracle 知識表明很多人都遇到過這個問題(Doc ID 19285025.8,Doc ID 1561121.1),唯一的建議是補丁“19285025”。 我們已經完成了這個補丁,但仍然沒有進展。 我們找到了 Oracle 文檔( 這里)來展示如何在“netmagr”的幫助下配置安全套接字層和添加密碼套件,但最終我知道這僅適用於 oracle DB 連接,但它沒有影響。 現在的問題是? 1. 如何解決 DBMS_LDAP.open_ssl 的“SSL 握手失敗”? 我們如何為 DBMS_LDAP.open_ssl 設置不同的密碼套件? 2. 任何使用 LDAPS 的替代 PL/SQL 包? 或者我們必須使用Java包並將其加載到數據庫中?

我已切換到java過程而不是Oracle DBMS_LDAP。 它運行良好,沒有SSL問題(除了擴展它的java的力量)。

    SET SERVEROUTPUT ON SIZE 5000;
CALL dbms_java.set_output(5000);

CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED LDAP AS
import javax.naming.*;
import javax.naming.directory.*;
import java.util.Hashtable;
/**
 * Java LDAP Package by ATK, 9/9/2016
 */
class ldap {
    public static int ldap_auth(String username, String my_password, String ldap_server) {

    Hashtable env = new Hashtable(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY, 
        "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, ldap_server ); //example "ldap://ldap.yourcompany.com:636"

    env.put(Context.SECURITY_PROTOCOL, "ssl");

    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "uid=" + username + ",OU=users,DC=company,DC=com");
    env.put(Context.SECURITY_CREDENTIALS, my_password);

    try {
        // Create initial context
        DirContext ctx = new InitialDirContext(env);

        System.out.println("Connection Successful.");

        ctx.close();
      return 0;
    } catch (NamingException e) {
        System.out.println("LDAP Connection: FAILED"); 
        e.printStackTrace();
      return -1;
    }
    }
};

--show errors java source ldap ; -- to check class compile

CREATE OR REPLACE FUNCTION ldap_auth (username in varchar2, my_password in varchar2, ldap_server in varchar2) RETURN NUMBER
AS LANGUAGE JAVA 
NAME 'ldap.ldap_auth (java.lang.String, java.lang.String, java.lang.String) return int';


call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldap.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldapqa.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', 'ldapdev.companyDomain.com', 'resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.53:636', 'connect,resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.54:636', 'connect,resolve' );
call dbms_java.grant_permission( 'MySchema', 'SYS:java.net.SocketPermission', '10.14.10.55:636', 'connect,resolve' );

現在你可以測試它:

SET SERVEROUTPUT ON SIZE 5000
CALL dbms_java.set_output(0);
declare 
  l_ret int ;
begin
  l_ret := ldap_auth ('myUser', 'myPassword', 'ldap://lds.companyDomain.com:636');
  DBMS_OUTPUT.put_line('Return = ' || l_ret );
end;

我很欣賞這是一篇舊帖子,但作為參考,事實證明 DBMS_LDAP 宣傳的密碼套件取決於open_ssl函數的sslauth參數。

sslauth設置為1 (無身份驗證)時,只會TLS_DH_anon_xxx密碼套件。 當使用23 (1 或 2 路身份驗證)時,所有密碼套件都將被廣告(OCI 中的 vanilla 19c ATP 數據庫中的 25 個套件)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM