2

我正在尝试创建一个连接到 Netgear WAG102(接入点)的 Java 软件,该软件必须获取我的 wifi 网络的连接日志。

我的软件已经可以与其他 Netgear 接入点(例如 WG302v2)一起使用,但我找不到让它与 WAG102 一起使用的方法。我不断收到一个

javax.net.ssl.SSLProtocolException:v2 证书中不允许扩展

在尝试打开与 AP 的安全 SSL 连接时。

附加信息:从 AP 发送的证书在 1 年前过期,所以我实施了臭名昭著的“TrustAllCerts”技巧,但仅此一项似乎没有帮助。

谷歌浏览器说证书是 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 和所有其他具有良好证书的站点正常工作。

4

1 回答 1

3

这里似乎有两个问题:

  • 首先,它不应该是 V4 证书。可以使用定制工具将此数字放在版本字段中,但没有与之匹配的规范。最新的X.509 规范仅升级到 V3:

    Version ::= INTEGER { v1(0), v2(1), v3(2) }
    
  • 其次,读取证书的 Java 代码使用了一个!=条件:

    (version.compare(CertificateVersion.V3) != 0)
    

    如果它不是 V3,则假定它是 V2(如果您认为不应该有 V4,这是有道理的)。我认为其他实现可能会让这个不正确的证书通过使用>=条件来代替。

如果可能,最简单的方法是在路由器上安装一个新的、正确的证书。(根据你的截图,它也使用了 MD5 签名,现在不推荐。)

编辑:似乎这个证书是用一个www.netgear.com主题备用名称颁发的(即它对该主机名有效),这在路由器上是没有意义的。如果您正在部署它,您应该真正安装自己的证书,即使它是自签名的。

无论如何,可能有一个解决方法。似乎 BouncyCastle 实现CertificateFactory(由 JSSE 使用)在版本方面更加灵活。如果您在 Sun 提供者之前使用 BC 提供者,这应该可以工作。您可以获取 BC 提供程序 jar 并使用它(在建立连接之前),例如:

Security.insertProviderAt(new BouncyCastleProvider(), 1);
于 2012-07-27T11:54:17.890 回答