我正在编写一个可以从远程服务器获取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:收到致命警报:内部错误”,它发生在“negotiate”方法中。我分析了wireshark跟踪信息,我确信这是因为服务器需要相互认证。现在,我想知道com.sun.jndi.ldap包中是否存在某些可能对此问题有用的类。有人可以帮忙吗?
答案 0 :(得分:3)
你做不到。如果在JDK中有这样的类,那将是不安全的。如果服务器需要客户端证书而没有客户端证书,则必须提供一个。这就是例外。