LDAPS-证书不应该分配给我尝试连接的主机名吗?
我尝试通过LDAPS协议连接到LDAP服务器,并使用服务器的IP定义URL 我使用的密钥库包含颁发给此服务器的证书,但主题DN包含主机名 它不应该失败吗 代码如下:LDAPS-证书不应该分配给我尝试连接的主机名吗?,ldap,certificate,Ldap,Certificate,我尝试通过LDAPS协议连接到LDAP服务器,并使用服务器的IP定义URL 我使用的密钥库包含颁发给此服务器的证书,但主题DN包含主机名 它不应该失败吗 代码如下: public class LdapConnection { private String host = "1.2.3.4"; //the correct ip... private String baseDn = "dc=x,dc=y,dc=com"; //the correct base DN priv
public class LdapConnection
{
private String host = "1.2.3.4"; //the correct ip...
private String baseDn = "dc=x,dc=y,dc=com"; //the correct base DN
private String username = "myUsername";
private String password = "myPassword";
private String connectionUrl = null;
public void connectLdaps() throws Exception
{
connectionUrl = "ldaps://" + host + "/" + baseDn;
System.out.println("Trying to connect to " + connectionUrl + " using LDAPS protocol");
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put("java.naming.ldap.derefAliases", "finding");
env.put(Context.PROVIDER_URL, connectionUrl);
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put("java.naming.ldap.factory.socket", MySocketFactory.class.getName());
new InitialLdapContext(env, null);
System.out.println("Connected successfully!");
}
public static void main(String[] args) throws Exception
{
LdapConnection ldapConnection = new LdapConnection();
ldapConnection.connectLdaps();
}
}
public class MySocketFactory extends SocketFactory
{
private static MySocketFactory instance = null;
private SSLContext sslContext = null;
private static String certFileName = "C:\\certs\\cert_by_hostname.cer";
public static SocketFactory getDefault()
{
if (instance == null)
{
try
{
instance = new MySocketFactory();
instance.initFactory();
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Returning null socket factory");
}
}
return instance;
}
private void initFactory() throws Exception
{
System.out.println("Initializing socket factory...");
InputStream certStream = new FileInputStream(certFileName);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Certificate certificate = certificateFactory.generateCertificate(certStream);
System.out.println("The certificate was generated. It is issued to " + ((X509Certificate)certificate).getSubjectDN());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, "myPassword".toCharArray());
new KeyStore.TrustedCertificateEntry(certificate);
keyStore.setCertificateEntry("myCert", certificate);
System.out.println("The Keystore was initialized.");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509", "SunJSSE");
trustManagerFactory.init(keyStore);
System.out.println("The TrustManagerFactory was initialized.");
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
System.out.println("The SSLContext was initialized.");
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException
{
System.out.println("In create socket, host is " + host + " and port is " + port);
return sslContext.getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException
{
return sslContext.getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException
{
return sslContext.getSocketFactory().createSocket(host, port, localHost, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
{
return sslContext.getSocketFactory().createSocket(address, port, localAddress, localPort);
}
}
当您通过HTTP或LDAP绑定到SSL并使用密钥库时,需要的是签署证书的受信任根的公钥。这与主机名是什么无关 从Windows的角度来看,这意味着签署证书的受信任根应该位于Windows密钥库中,在该实例中称为证书存储 对于大多数其他应用程序来说,它是某种密钥库。基于Java的应用程序使用keytool对其进行操作 因此,只要可信根是已知的,并且隐含可信的,那么它就假定证书链是好的和可信任的 因此,除非您使用服务器证书进行相互身份验证,否则在通过SSL的普通LDAP或通过SSL的常规HTTP的情况下不太可能,否则我认为这不重要
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: hostname of the server '1.2.3.4' does not match the hostname in the server's certificate.
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.verify(Unknown Source)
at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(Unknown Source)
at ldapconnection.LdapConnection.connectTLS(LdapConnection.java:84)
at ldapconnection.LdapConnection.main(LdapConnection.java:92)
Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 1.2.3.4 found
at sun.security.util.HostnameChecker.matchIP(Unknown Source)
at sun.security.util.HostnameChecker.match(Unknown Source)
... 4 more