我开发使用 Volley 的android应用程序。 所有通信都通过 HTTPS 连接完成。 因为我在本地环境中测试它,所以我使用Tomcat的自签名证书。
之前,我只有android 2.3 和 3.0 设备。现在我还 4.1和4.4 。
我的实现使用此方法:http://developer.android.com/training/articles/security-ssl.html(部分未知的证书颁发机构) 在Android 高达4.1 的设备上,它可以完美运行。带有自定义证书的SSLSocketFactory传递给Volley:
Volley.newRequestQueue(getApplicationContext(), new HurlStack(null, socketFactory));
但Android 4.1+会发生什么? 为什么它不起作用? 我也尝试使用 NullX509TrustManager :
private static class NullX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
但它仍然不起作用......
答案 0 :(得分:3)
我已经用这里提到的解决方案解决了这个问题:
http://developer.android.com/training/articles/security-ssl.html
主机名验证的常见问题
添加自定义主机名验证程序,在Volley项目中为我的主机名返回true并编辑HurlStack openConnection方法:
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {
((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
((HttpsURLConnection)connection).setHostnameVerifier(new CustomHostnameVerifier());
}
答案 1 :(得分:0)
如果您已经有一个 .crt 文件,并希望将其附加到 Volley ,则可以按照以下两个简单步骤进行操作。
第1步:将此方法写入您的代码。
public SSLSocketFactory getSocketFactory(Context context)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
// Load CAs from an InputStream (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.myFile));
// I paste my myFile.crt in raw folder under res.
Certificate ca;
//noinspection TryFinallyCanBeTryWithResources
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
第2步:在使用Volley进行任何请求之前,只需将以下内容添加到此行即可。
HttpsURLConnection.setDefaultSSLSocketFactory(getSocketFactory(context));
Android Studio会要求您在try / catch中将该行括起来,以获取我们方法抛出的所有异常。所以就让它做。
快乐编码!
答案 2 :(得分:-1)
我找到的最简单的方法是adding this class并从new NukeSSLCerts().nuke();
方法
#include <iostream>
using namespace std;
void main()
{
//Initial array input
int state_array[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 };
int temp[1] = { 0 };
int array_size = sizeof(state_array) / (sizeof(temp[0]));
for (int i = 0; i<65535; i++)
{
temp[0] = state_array[15];
//XOR Values
for (int j = 0; j<16; j++) {
if ((j == 2 || j == 3 || j == 5) && state_array[15] == 1) {
state_array[j] = !state_array[j];
}
}
//Shift values
for (int j = array_size-1; j>0; j--)
{
if (j == 0) {
state_array[0] = temp[0];
}
else {
state_array[j] = state_array[j-1];
}
}
}
}
它将使凌空信任所有SSL证书
答案 3 :(得分:-1)
信任所有SSL证书: - 如果要在测试服务器上进行测试,可以绕过SSL。 但是不要将此代码用于生产。
public static class NukeSSLCerts {
protected static final String TAG = "NukeSSLCerts";
public static void nuke() {
try {
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
} catch (Exception e) {
}
}
}
请在Activity或您的Application Class中的onCreate()函数中调用此函数。
NukeSSLCerts.nuke();
这可以用于Android中的Volley。 更多参考 https://newfivefour.com/android-trust-all-ssl-certificates.html