2

Wi-Fiネットワークの接続ログを取得する必要があるNetgearWAG102(アクセスポイント)に接続するJavaソフトウェアを作成しようとしています。

私のソフトウェアはすでに他のNetgearアクセス​​ポイント(たとえば、WG302v2)で動作しますが、WAG102で動作させる方法が見つかりません。私は受け取り続けます

javax.net.ssl.SSLProtocolException:v2証明書で許可されていない拡張機能

APへの安全なSSL接続を開こうとしている間。

追加情報: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および他のすべてのサイトで適切な証明書を使用して正しく機能します。

4

1 に答える 1

3

ここには 2 つの問題があるようです。

  • まず、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 に答える