使用volley进行https请求,Hostname xxxxx not verified:
看了一下源码,主要是因为此方法的 getSubjectAltNames(certificate, ALT_DNS_NAME)
返回为null
,具体原因不明。
/**
* Returns true if {@code certificate} matches {@code hostName}.
*/
private boolean verifyHostName(String hostName, X509Certificate certificate) {
hostName = hostName.toLowerCase(Locale.US);
boolean hasDns = false;
for (String altName : getSubjectAltNames(certificate, ALT_DNS_NAME)) {
hasDns = true;
if (verifyHostName(hostName, altName)) {
return true;
}
}
if (!hasDns) {
X500Principal principal = certificate.getSubjectX500Principal();
// RFC 2818 advises using the most specific name for matching.
String cn = new DistinguishedNameParser(principal).findMostSpecific("cn");
if (cn != null) {
return verifyHostName(hostName, cn);
}
}
return false;
}
解决方法是:
public class YxpHurlStack extends HurlStack {
public YxpHurlStack(UrlRewriter urlRewriter, SSLSocketFactory sslSocketFactory) {
super(urlRewriter, sslSocketFactory);
}
@Override
protected HttpURLConnection createConnection(URL url) throws IOException {
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) super.createConnection(url);
try {
httpsURLConnection.setHostnameVerifier(getHostnameVerifier());
} catch (Exception e) {
e.printStackTrace();
}
return httpsURLConnection;
}
// Let's assume your server app is hosting inside a server machine
// which has a server certificate in which "Issued to" is "localhost",for example.
// Then, inside verify method you can verify "localhost".
// If not, you can temporarily return true
private HostnameVerifier getHostnameVerifier() {
return new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
//return true; // verify always returns true, which could cause insecure network traffic due to trusting TLS/SSL server certificates for wrong hostnames
// HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
// boolean isVerify = hv.verify("121.25.201.236", session);
// return isVerify;
return true;
}
};
}
}
然后:
public static RequestQueue newRequestQueue(Context context, int maxDiskCacheBytes) {
SSLSocketFactory sslSocketFactory = initSSLSocketFactory(context);
YxpHurlStack stack = new YxpHurlStack(null, sslSocketFactory);
return Volley.newRequestQueue(context, stack, maxDiskCacheBytes);
}
参考:
https://stackoverflow.com/questions/32403479/volley-ssl-hostname-was-not-verified
网友评论