Я получаю следующее исключение, пытаясь подключиться к веб-службе, используя HttpsURLConnection, запущенную на хосте в той же сети. Firewall отключен. Интересная часть заключается в том, что если я запустил следующий код через стандартную среду java JRE 1.7 по умолчанию в eclipse, все будет хорошо.
Но если я использую эти функции в коде продукта, который имеет свою собственную папку 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();
}
Мне нужно, чтобы эти функции работали в коде продукта. Любая помощь будет оценена. Заранее спасибо !!
Я явно установил поставщиков для KeyManagerFactory и SSLContext в "SunJSSE", и это сработало!
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance("SunX509","SunJSSE");
SSLContext context = SSLContext.getInstance("TLS","SunJSSE");
Возможно, попытка использовать SunX509
KeyManagerFactory
может привести к путанице с другими фабриками за кулисами, когда RSA Jsafe имеет более высокий приоритет, чем поставщик Sun.
Если RSA Jsafe предоставляет собственную реализацию KeyManagerFactory, попробуйте:
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
(Если вы действительно не хотите, чтобы SunX509 KMF, используя алгоритм по умолчанию в вашей причине, как правило, лучший выбор, чтобы не зависел от конкретных поставщиков. То же самое можно сказать о TrustManagerFactories.)