使用 Retrofit 2 获取 SSLException
Getting SSLException using Retrofit 2
我正在创建授权应用程序,我正在使用 Retrofit 2。当我进行调用时,它会转到 onFailure 方法并出现异常
"javax.net.ssl.SSLException: Connection closed by peer"
但问题是,昨天这很管用。今天它给出了例外。我在互联网上找到了一些 , or this How to add TLS v 1.0 and TLS v.1.1 with Retrofit,但这对我没有帮助。任何想法如何解决它。在后端启用 TLS1.2。
public class RegistrationFragment extends BaseFragment {
View mainView;
ApiClient apiClient = ApiClient.getInstance();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate
(R.layout.registration_fragment, container, false);
//Calling the authorization method
registerCall();
}
});
return mainView;
}
//User authorization method
public void registerCall() {
Call<ResponseBody> call = apiClient.registration(supportopObj);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
//Calling the clientCall method for getting the user clientID and clientSecret
Toast.makeText(getActivity(), "Registration Successful ",
Toast.LENGTH_SHORT).show();;
} else {
//if the response not successful
Toast.makeText(getActivity(), "Could not register the user maybe already registered ",
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getActivity(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
}
}
不是因为Retrofit,而是因为okhttp。如果你使用 okhttp version 3.x ,你会遇到这个问题。直接的解决方案是使用 okhttp 版本 2.x。要补充的另一件事是,此问题仅发生在 Android 版本 16-20 Link for reference
我在我的 OkHttp 初始化中使用了类似的东西 class,但是在这里使用安全吗?
我创建了一个新的classTls12SocketFactory.class
在这儿。
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
}
我在 OkHttp 初始化中做了类似的事情 class。
X509TrustManager trustManager = null;
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
trustManager = (X509TrustManager) trustManagers[0];
} catch (KeyStoreException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
OkHttpClient.Builder client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS);
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, new TrustManager[] { trustManager }, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()), trustManager);
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();
client.connectionSpecs(Collections.singletonList(cs));
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
name = new Retrofit.Builder()
.baseUrl(endpoint)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
那么在 Android studio 中使用此代码是否安全。而且这段代码将来会不会有任何问题?谢谢你。我想我的回答对其他人也有帮助。
我正在创建授权应用程序,我正在使用 Retrofit 2。当我进行调用时,它会转到 onFailure 方法并出现异常
"javax.net.ssl.SSLException: Connection closed by peer"
但问题是,昨天这很管用。今天它给出了例外。我在互联网上找到了一些
public class RegistrationFragment extends BaseFragment {
View mainView;
ApiClient apiClient = ApiClient.getInstance();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate
(R.layout.registration_fragment, container, false);
//Calling the authorization method
registerCall();
}
});
return mainView;
}
//User authorization method
public void registerCall() {
Call<ResponseBody> call = apiClient.registration(supportopObj);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
//Calling the clientCall method for getting the user clientID and clientSecret
Toast.makeText(getActivity(), "Registration Successful ",
Toast.LENGTH_SHORT).show();;
} else {
//if the response not successful
Toast.makeText(getActivity(), "Could not register the user maybe already registered ",
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getActivity(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
}
}
不是因为Retrofit,而是因为okhttp。如果你使用 okhttp version 3.x ,你会遇到这个问题。直接的解决方案是使用 okhttp 版本 2.x。要补充的另一件事是,此问题仅发生在 Android 版本 16-20 Link for reference
我在我的 OkHttp 初始化中使用了类似的东西 class,但是在这里使用安全吗?
我创建了一个新的classTls12SocketFactory.class
在这儿。
public class Tls12SocketFactory extends SSLSocketFactory {
private static final String[] TLS_V12_ONLY = {"TLSv1.2"};
final SSLSocketFactory delegate;
public Tls12SocketFactory(SSLSocketFactory base) {
this.delegate = base;
}
@Override
public String[] getDefaultCipherSuites() {
return delegate.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return delegate.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return patch(delegate.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
return patch(delegate.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return patch(delegate.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
return patch(delegate.createSocket(address, port, localAddress, localPort));
}
private Socket patch(Socket s) {
if (s instanceof SSLSocket) {
((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
}
return s;
}
}
我在 OkHttp 初始化中做了类似的事情 class。
X509TrustManager trustManager = null;
try {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
trustManager = (X509TrustManager) trustManagers[0];
} catch (KeyStoreException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
OkHttpClient.Builder client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS);
try {
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, new TrustManager[] { trustManager }, null);
client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()), trustManager);
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.build();
client.connectionSpecs(Collections.singletonList(cs));
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
name = new Retrofit.Builder()
.baseUrl(endpoint)
.client(client.build())
.addConverterFactory(GsonConverterFactory.create())
.build();
那么在 Android studio 中使用此代码是否安全。而且这段代码将来会不会有任何问题?谢谢你。我想我的回答对其他人也有帮助。