【问题标题】:how to get ldap certificate bypass the mutual certification using Java如何使用Java绕过相互认证获取ldap证书
【发布时间】:2013-08-19 21:24:12
【问题描述】:

我正在编写一个可以从远程服务器获取 Ldap 证书的项目。当服务器不需要相互认证时,它适用于一般模式。但是当我尝试需要相互认证的服务器时,它会失败。代码如下:

    String serverSpec = null;
    boolean enableAnonSuites = false;
    boolean isTracing = false;

    // Try and parse command line arguments.
    try {

        serverSpec = "ldap://10.47.16.60:389";
    }

    catch (Exception e) {
        trace(true,e.toString());
        usage();
        return;
    }

    try {

        // Create a SocketFactory that will be given to LDAP for 
        // building SSL sockets
        MySocketFactory msf = new MySocketFactory(isTracing,
                enableAnonSuites);

        // Set up environment for creating initial context
        Hashtable env = new Hashtable(11);
        env.put(Context.INITIAL_CONTEXT_FACTORY, 
                "com.sun.jndi.ldap.LdapCtxFactory");


        // Must use the name of the server that is found in its certificate
        env.put(Context.PROVIDER_URL, 
                serverSpec
                );

        // Create initial context
        trace(isTracing,"Creating new Ldapcontext");
        LdapContext ctx = new InitialLdapContext(env, null);

        // Start 
        trace(isTracing,"Performing StartTlsRequest");
        StartTlsResponse tls = null;

        try {
            tls = (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
        }
        catch (NamingException e) {
            trace(true,"Unable to establish SSL connection:\n"
                    +e);
            return;
        }


        // The default JSSE implementation will compare the hostname of
        // the server with the hostname in the server's certificate, and
        // will not proceed unless they match.  To override this behaviour,
        // you have to provide your own HostNameVerifier object.  The 
        // example below simply bypasses the check

        tls.setHostnameVerifier(new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) 
            {
                return true;
            }
        });
        // Negotiate SSL on the connection using our own SocketFactory
        trace(isTracing,"Negotiating SSL");
        SSLSession sess = null;
        sess = tls.negotiate(msf);

        X509Certificate[] cert = sess.getPeerCertificateChain();

异常信息如下:“javax.net.ssl.SSLException: Received fatal alert: internal error”,发生在“negotiate”方法。我分析了wireshark的trace信息,确定这是因为服务器需要相互认证。现在,我想知道 com.sun.jndi.ldap 包中是否有某些类可能对这个问题有用。有人可以帮忙吗?

【问题讨论】:

    标签: java ldap certificate jndi starttls


    【解决方案1】:

    你不能。如果JDK中有这样的类,那将是不安全的。如果服务器需要客户端证书并且没有它就无法运行,则您必须提供一个。这就是例外的意义所在。

    【讨论】:

    • +1 表示强调。如果服务器要求,您不能绕过相互身份验证。
    • 谢谢。我想我的问题没有说清楚。我的意思是,因为最终目标是获取证书,我可以从wirehack跟踪中看到服务器已经将证书发送给我(相互认证意味着服务器将证书发送给客户端,客户端响应其证书) .并且客户端确实在握手完成之前获得了证书。所以,问题是,即使服务器已经将证书发送给我,我也没有找到获取证书的方法。有没有办法在握手完成之前用 Java 获取证书?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    • 1970-01-01
    相关资源
    最近更新 更多