繁体   English   中英

java.net.SocketException:软件导致连接中止:使用其他jre安全性时recv失败

[英]java.net.SocketException: Software caused connection abort: recv failed when using different jre security

尝试使用在同一网络中的主机上运行的HttpsURLConnection连接到Web服务时遇到以下异常。防火墙已关闭。 有趣的是,如果我在Eclipse中通过默认的Java JRE 1.7环境运行以下代码,则一切正常。

但是,如果我在具有自己的jre文件夹的产品代码中使用这些功能,则会引发以下异常-

Caused by: java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:173)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at com.rsa.sslj.x.aP.c(Unknown Source)
    at com.rsa.sslj.x.aP.a(Unknown Source)
    at com.rsa.sslj.x.aP.a(Unknown Source)
    at com.rsa.sslj.x.aP.h(Unknown Source)
    at com.rsa.sslj.x.cy.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)

我注意到java.security文件中的安全提供程序列表有所不同。

这是清单-

security.provider.1=com.rsa.jsafe.provider.JsafeJCE
security.provider.2=com.rsa.jsse.JsseProvider
security.provider.3=sun.security.provider.Sun
security.provider.4=sun.security.rsa.SunRsaSign
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC
security.provider.11=sun.security.mscapi.SunMSCAPI

这些是我的职能-

private InputStream Get(URL url,String keyStoreString, String keyStorePassword) {
    SSLSocketFactory sslFactory;
    try {
        sslFactory = getSSLSocketFactory(keyStoreString, keyStorePassword);     
        javax.net.ssl.HttpsURLConnection
                .setDefaultHostnameVerifier(new  javax.net.ssl.HostnameVerifier() {
                    public boolean verify(String hostname,
                            javax.net.ssl.SSLSession sslSession) {
                        if (hostname.equals("vmm")) {
                            return true;
                        }
                        return false;
                    }
                });
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
        con.setSSLSocketFactory(sslFactory);
        con.setRequestMethod("GET");
        con.setRequestProperty("Accept", "application/json");
        InputStream responseStream = con.getInputStream();
        return responseStream;
      }catch (Exception e) {
        //log errer
      }
}
private SSLSocketFactory getSSLSocketFactory(String keyStoreString,
        String password) throws KeyStoreException,
        NoSuchAlgorithmException, CertificateException, IOException,
        UnrecoverableKeyException, KeyManagementException, AzureException {
      KeyStore ks = getKeyStore(keyStoreString, password);
      KeyManagerFactory keyManagerFactory = KeyManagerFactory
            .getInstance("SunX509");
      keyManagerFactory.init(ks, password.toCharArray());
      // Trustmanager which trusts all certificate. Not a good idea in
      // production code.
      final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
        @Override
        public void checkClientTrusted(final X509Certificate[] chain,
                final String authType) {
        }

        @Override
        public void checkServerTrusted(final X509Certificate[] chain,
                final String authType) {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    } };

    SSLContext context = SSLContext.getInstance("TLS");
    context.init(keyManagerFactory.getKeyManagers(), trustAllCerts,
            new SecureRandom());

    return context.getSocketFactory();
}

我需要在产品代码中使用这些功能。 任何帮助将不胜感激。 提前致谢 !!

当RSA Jsafe的优先级高于Sun提供程序的优先级时,尝试使用SunX509 KeyManagerFactory可能会与幕后的其他工厂混淆。

如果RSA Jsafe提供了自己的KeyManagerFactory实现,则可以尝试:

KeyManagerFactory keyManagerFactory = 
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

(除非您真的希望SunX509 KMF,在您的原因中使用默认算法通常是更好的选择,这样就不必依赖特定的提供程序。对于TrustManagerFactories,也适用)。

我将KeyManagerFactory和SSLContext的提供程序显式设置为'SunJSSE',并且有效!

KeyManagerFactory keyManagerFactory = KeyManagerFactory
            .getInstance("SunX509","SunJSSE");

SSLContext context = SSLContext.getInstance("TLS","SunJSSE");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM