java - 忽略证书时出现 CertificateException
问题描述
我正在尝试 LDAPS 身份验证,但我忽略了 SSL 证书。
public class BlindSSLSocketFactoryTest extends SocketFactory {
private static SocketFactory blindFactory = null;
static {
TrustManager[] blindTrustMan = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] c, String a) {
}
public void checkServerTrusted(X509Certificate[] c, String a) {
}
}};
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, blindTrustMan, new java.security.SecureRandom());
blindFactory = sc.getSocketFactory();
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
public static SocketFactory getDefault() {
return new BlindSSLSocketFactoryTest();
}
public Socket createSocket(String arg0, int arg1) throws IOException,
UnknownHostException {
return blindFactory.createSocket(arg0, arg1);
}
public Socket createSocket(InetAddress arg0, int arg1) throws IOException {
return blindFactory.createSocket(arg0, arg1);
}
public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
throws IOException, UnknownHostException {
return blindFactory.createSocket(arg0, arg1, arg2, arg3);
}
public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
int arg3) throws IOException {
return blindFactory.createSocket(arg0, arg1, arg2, arg3);
}
}
还
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, LDAP_SERVER);
env.put("java.naming.ldap.factory.socket", BlindSSLSocketFactoryTest.class.getName());
在开发 PC 上运行时,它按预期工作:证书被忽略,身份验证成功。
在使用 OpenJDK 的 ARM 设备上运行时,我得到了
javax.naming.CommunicationException: simple bind failed: 10.1.10.201:636 [Root exception is javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present]
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2791)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:319)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:192)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:210)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:153)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:83)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:216)
at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
at LDAP1.main(LDAP1.java:59)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:931)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at com.sun.jndi.ldap.Connection.run(Connection.java:877)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.cert.CertificateException: No subject alternative names present
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:145)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:94)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:459)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(SSLContextImpl.java:1026)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(SSLContextImpl.java:993)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
... 12 more
为什么会这样,我怎样才能让设备表现得像电脑一样?
请不要评论“你应该修复证书”,谢谢。
解决方案
我需要禁用端点识别
-Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true
推荐阅读
- css - 从一个元素到另一个元素的动画
- sql - Oracle SQL FETCH NEXT 跨多行
- r - R - 基于前一行和其他列的新因子变量。优化Ifelse
- apache - Mod-Rewrite 使用转义字符串代替
- html - flexbox,第一个元素块换行
- microsoft-graph-api - 创建架构扩展会给出“名称包含无效字符”
- php - Mysql / PHP将空值上传到时间戳类型属性中
- html2canvas - html2canvas 截图后复选框不可见
- javascript - 如何在 Bootstrap 4.1 中单击汉堡按钮时在大屏幕上水平显示菜单项
- docker - 使用 yaml 在 Gitlab 中使用版本标记 Docker 映像