2013-08-19 2 views
0

Я пишу проект, который может получить сертификат Ldap с удаленного сервера. Он отлично работает для общего режима, когда сервер не требует взаимной сертификации. Но когда я пытаюсь использовать сервер, требующий взаимной сертификации, он терпит неудачу. Вот код:Как получить сертификат ldap обходить взаимную сертификацию с помощью Java

информация
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: Получен фатальным предупреждение: внутренняя ошибка», и это происходит в методе «вести переговоры». И я проанализировал информацию о трассировке проводников и уверен, что это связано с тем, что сервер требует взаимной сертификации. Прямо сейчас, мне интересно, есть ли какой-то класс, который находится в пакете com.sun.jndi.ldap, который может быть полезен для этой проблемы. Может ли кто-нибудь помочь?

ответ

3

Вы не можете. Если бы в JDK был такой класс, это было бы неуверенно. Если сервер требует сертификат клиента и не будет работать без него, вы должны его предоставить. Это точка исключения.

+0

+1 для акцента. Вы не можете обойти взаимную аутентификацию, если это требуется сервером. – Syon

+0

Спасибо. Думаю, я не задал вопрос. Я имею в виду, потому что конечная цель - получить сертификат, и я вижу на трассе проводов, что сервер уже отправил мне сертификат (взаимная сертификация означает, что сервер отправляет сертификат клиенту и ответ клиента с его сертификатом) , И клиент получает сертификат до завершения рукопожатия. Итак, проблема в том, что я не нашел способ получить сертификат, даже если сервер уже отправил его мне. Есть ли способ получить сертификат на Java до завершения рукопожатия? – user2528892

Смежные вопросы