我正在尝试创建一个连接到Netgear WAG102(接入点)的Java软件,它必须获取我的wifi网络的连接日志。
我的软件已经可以与其他Netgear接入点(WG302v2,用于等级)一起使用,但我找不到让它与WAG102一起使用的方法。 我继续收到
尝试打开与AP的安全SSL连接时javax.net.ssl.SSLProtocolException:v2证书中不允许使用扩展名
。
其他信息:从AP发送的证书在1年前过期,因此我实施了臭名昭着的“TrustAllCerts”技巧,但仅此一点似乎没有帮助。
Google Chrome表示该证书是版本v4,但是我的java软件继续说它是版本v2,当它检查证书扩展时给出了该异常(据我所知,版本v2不支持扩展)
我的问题是:尽管存在这个问题,有没有办法让它发挥作用?
这是我的代码:
private HttpsURLConnection createConnection(URL url) throws IOException{
HttpsURLConnection con=(HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Authorization", "Basic " + "**********");
con.setHostnameVerifier(new HostnameVerifier(){public boolean verify(String hostname, SSLSession session){return true;}});
TrustManager[] trustAllCerts=null;
SSLContext sslContext=null;
SSLSocketFactory sslSocketFactory;
try{
trustAllCerts = new TrustManager[]{ new X509TrustManager(){
public X509Certificate[] getAcceptedIssuers(){return null;}
public void checkClientTrusted(X509Certificate[] chain, String authType){}
public void checkServerTrusted(X509Certificate[] chain, String authType){}
}};
sslContext = SSLContext.getInstance( "SSL" );
sslContext.init( null, trustAllCerts, new java.security.SecureRandom() );
sslSocketFactory = sslContext.getSocketFactory();
con.setSSLSocketFactory( sslSocketFactory );
System.out.println("Response Code : " + con.getResponseCode());
System.out.println("Cipher Suite : " + con.getCipherSuite());
Certificate[] certs = con.getServerCertificates();
for(Certificate cert : certs){
System.out.println("Cert ext : "+cert);
System.out.println("Cert Type : " + cert.getType());
System.out.println("Cert Hash Code : " + cert.hashCode());
System.out.println("Cert Public Key Algorithm : " + cert.getPublicKey().getAlgorithm());
System.out.println("Cert Public Key Format : " + cert.getPublicKey().getFormat());
System.out.println("\n");
}
} catch (Exception e){e.printStackTrace();}
//printHTTPSCert(con);
return con;
}
我在调用con.getResponseCode()
时遇到异常,主要是因为我认为这是连接打开的时候。
此程序可与www.google.com以及所有其他具有良好证书的网站一起正常使用。
答案 0 :(得分:3)
这里似乎有两个问题:
首先,它不应该是V4证书。可以使用自定义工具将此数字放在版本字段中,但没有与之匹配的规范。最新的X.509 specification只能达到V3:
Version ::= INTEGER { v1(0), v2(1), v3(2) }
其次,the Java code that reads the certificate使用!=
条件:
(version.compare(CertificateVersion.V3) != 0)
如果它不是V3,它假定它是V2(如果你认为不应该有V4,这是有道理的)。我认为其他实现可能会通过使用>=
条件来使用此错误证书。
最简单的方法是尽可能在路由器上安装新的正确证书。 (根据你的截图,它也使用了MD5签名,现在不推荐使用。)
编辑:此证书似乎还发布了www.netgear.com
主题备用名称(即它对该主机名有效),这在路由器上是无意义的。如果你正在部署它,你应该真正安装自己的证书,即使它是自签名的。
无论如何,可能有一种解决方法。似乎BouncyCastle实现CertificateFactory
(由JSSE使用)在版本方面更灵活。如果您在Sun提供商之前使用BC提供商,这应该有效。您可以获取BC提供程序jar并使用它(在建立连接之前),例如:
Security.insertProviderAt(new BouncyCastleProvider(), 1);