技术联盟

关于HttpUrlConnection请求网络加载证书与不加载证书的区别

测试的3个网址分别为:

String uri1 = “https://mportal.tianjihuifu.com/tjhf/loginRegist/login?uname=13265468238&pwd=123456”;

String uri2 = “https://mportal.tjhf.com/tjhf/loginRegist/login?uname=13265468238&pwd=123456”;

String uri = “https://www.baidu.com/”;

中间用到的证书为cer_test.crt,证书信息为:CN=console.haitest.com, C=CN。分别测试了加载证书与不加载证书请求3个不同的网址的日志。

证书为cer_test.crt,没有HostnameVerifier
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.haitest.com/hai/loginRegist/login?uname=13265468238&pwd=123456
E/==####DROXY####===: (*_*)响应结果:{“data”:72771,”result”:true,”resultCode”:2000}
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.hai.com/hai/loginRegist/login?uname=13265468238&pwd=123456
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
E/==####DROXY####===: (*_*)发送请求(get):https://www.baidu.com/
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
证书为cer_test.crt,HostnameVerifier :return true
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.haitest.com/hai/loginRegist/login?uname=13265468238&pwd=123456
E/==####DROXY####===: (*_*)响应结果:{“data”:72771,”result”:true,”resultCode”:2000}
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.hai.com/hai/loginRegist/login?uname=13265468238&pwd=123456
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
E/==####DROXY####===: (*_*)发送请求(get):https://www.baidu.com/
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
证书为cer_test.crt,HostnameVerifier :return hostname.equals(session.getPeerHost())
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.haitest.com/hai/loginRegist/login?uname=13265468238&pwd=123456
E/==####DROXY####===: (*_*)响应结果:{“data”:72771,”result”:true,”resultCode”:2000}
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.hai.com/hai/loginRegist/login?uname=13265468238&pwd=123456
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
E/==####DROXY####===: (*_*)发送请求(get):https://www.baidu.com/
W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
证书为null,没有HostnameVerifier
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.haitest.com/hai/loginRegist/login?uname=13265468238&pwd=123456
E/==####DROXY####===: (*_*)发送请求(get):https://mportal.hai.com/hai/loginRegist/login?uname=13265468238&pwd=123456
E/==####DROXY####===: (*_*)响应结果:{“data”:72771,”result”:true,”resultCode”:2000}
E/==####DROXY####===: (*_*)发送请求(get):https://www.baidu.com/
E/==####DROXY####===: (*_*)响应结果:<!DOCTYPE html>
<html><!–STATUS OK–><script>var PageTimer = {};PageTimer.start = new Date().getTime();</

测试结果总结得出:HttpURLConnection连接网络

无加载证书,可以请求任何https网址,
加载证书,且信任证书密钥,则只能请求和证书网址一致的网址,不管HostnameVerifier返回的是true or false
加载证书,且信任所有证书,则可以请求任何https网址,
只要是https网址,不管有没有使用sslSocketFactory,传输的都是加密密文
下面给出网络请求的主要部分代码

/**
* Created by 黄海 on 2016/10/8.
*/
public class HttpUtils {
private static final String BOUNDARY = “——WebKitFormBoundaryXt9bHBmce2A1Qt0j”;
private static final int CONNECTION_TIMEOUT = 7 * 1000;
private static final int SOCKET_TIMEOUT = 7 * 1000;
private static SSLSocketFactory sslSocketFactory;
private static CookieManager cookieManager;
private static final String COOKIES_HEADER = “Set-Cookie”;
private static Map<String, String> requestHeader = new HashMap<>();

public static void init(Context context) {
cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);//如果这里设置了,就不需要手动管理cookie了

KeyStore keyStore = null;
InputStream is = null;
CertificateFactory cf = null;

try {
cf = CertificateFactory.getInstance(“X.509”);
is = context.getResources().getAssets().open(“cer_test.crt”);
Certificate ca = cf.generateCertificate(is);
Logger.e(“ca=” + ((X509Certificate) ca).getSubjectDN());

// Create a KeyStore containing our trusted CAs
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry(“ca”, ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String defaultAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(defaultAlgorithm);
tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance(“TLS”);
sslContext.init(null, tmf.getTrustManagers(), null);//信任证书密钥
// sslContext.init(null, new TrustManager[]{new UnSafeTrustManager()}, null);//信任所有
sslSocketFactory = sslContext.getSocketFactory();

} catch (Exception e) {
e.printStackTrace();
}
}

public static String get(String uri) {
try {
byte[] bytes = performRequest(new URL(uri), null, null, Method.GET);
if (bytes != null && bytes.length > 0) {
String result = new String(bytes);
Logger.e(“响应结果:” + result);
return result;
} else {
Logger.e(“请求出错:请检查好网络设置”);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

public static String post(String url, Map<String, File> files) {
try {
byte[] bytes = performRequest(new URL(url), null, files, Method.POST);
if (bytes != null && bytes.length > 0) {
String result = new String(bytes);
Logger.e(“响应结果:” + result);
return result;
} else {
Logger.e(“请求出错:请检查好网络设置”);
}
} catch (Exception e) {
Logger.e(“请求出错:请检查好网络设置”);
e.printStackTrace();
}
return null;
}

private static byte[] performRequest(URL url, byte[] params, Map<String, File> files, int method) throws Exception {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(CONNECTION_TIMEOUT);
connection.setReadTimeout(SOCKET_TIMEOUT);
connection.setUseCaches(false);
connection.setDoInput(true);
if (“https”.equals(url.getProtocol()) && sslSocketFactory != null) {
((HttpsURLConnection) connection).setSSLSocketFactory(sslSocketFactory);
((HttpsURLConnection) connection).setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Log.e(“hhp”, “verify: ” + hostname + “|” + session.getPeerHost());
return hostname.equals(session.getPeerHost());
// return true;
}
});
}
//设置请求头
for (String headerName : getRequestHeader().keySet()) {
connection.addRequestProperty(headerName, getRequestHeader().get(headerName));
}
//设置cookie
// if (cookieManager.getCookieStore().getCookies().size() > 0) {
// connection.setRequestProperty(“Cookie”,
// TextUtils.join(“;”, cookieManager.getCookieStore().getCookies()));
// Logger.i(“Cookie=” + connection.getRequestProperty(“Cookie”));
// }
setConnectionParametersForRequest(connection, params, method);
// setConnectionParametersForRequest(connection, files);

int responseCode = connection.getResponseCode();
if (responseCode != 200) {
Logger.e(“请求出错:responseCode=” + responseCode);
throw new IOException(“Could not retrieve response code from HttpUrlConnection.”);
}
if (hasResponseBody(method, responseCode)) {
// readResponseCookies(url, connection);
InputStream inputStream;
try {
inputStream = connection.getInputStream();
} catch (IOException ioe) {
inputStream = connection.getErrorStream();
}
if (inputStream != null) {
int length = connection.getContentLength();
byte[] buffer = new byte[length];
inputStream.read(buffer);
return buffer;
}
}
return new byte[0];
}

/**
* 设置请求参数
*
* @param connection
* @param postBody
* @param method
* @throws IOException
*/
private static void setConnectionParametersForRequest(HttpURLConnection connection, byte[] postBody, int method) throws IOException {
switch (method) {
case Method.POST:
byte[] body = postBody;
if (body != null) {
connection.setDoOutput(true);
connection.setRequestMethod(“POST”);
connection.setRequestProperty(“Content-Type”, “application/x-www-form-urlencoded; charset=utf-8”);
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(postBody);
out.close();
}
break;
case Method.GET:
connection.setRequestMethod(“GET”);
Logger.e(“发送请求(get):” + connection.getURL().toString());
break;
}
}

/**
* 上传文件
*
* @param connection
* @param files
* @throws IOException
*/
private static void setConnectionParametersForRequest(HttpURLConnection connection, Map<String, File> files) throws IOException {
String contentType = “application/octet-stream”;
// String contentType=”image/jpeg”;
if (files != null && files.size() > 0) {
connection.setDoOutput(true);
connection.setRequestMethod(“POST”);
connection.setRequestProperty(“Content-Type”, “multipart/form-data; boundary=” + BOUNDARY);
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
Iterator<Map.Entry<String, File>> iterator = files.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, File> next = iterator.next();
String name = next.getKey();
File value = next.getValue();
if (value == null)
return;
StringBuilder strBuf = new StringBuilder();
strBuf.append(“\r\n”).append(“–“).append(BOUNDARY).append(“\r\n”);
strBuf.append(“Content-Disposition: form-data; name=\”” + name + “\”; filename=\”” + value.getName() + “\”\r\n”);
strBuf.append(“Content-Type:” + contentType + “\r\n\r\n”);
out.write(strBuf.toString().getBytes());
DataInputStream dis = new DataInputStream(new FileInputStream(value));
int bytes = -1;
byte[] buffer = new byte[1024 * 4];
while ((bytes = dis.read(buffer)) != -1) {
out.write(buffer);
}
dis.close();
}
byte[] endData = (“\r\n–” + BOUNDARY + “–\r\n”).getBytes();
out.write(endData);
out.flush();
out.close();
}
Logger.e(“发送请求(post):” + connection.getURL().toString());
if (files != null) {
for (File file : files.values()) {
Logger.e(“发送文件:” + new String(file.getName()));
}
}
}

private static Map<String, String> getRequestHeader() {
requestHeader.put(“Connection”, “Keep-Alive”);
requestHeader.put(“Accept-Encoding”, “identity”);//高版本避免conn.getContentLength()==-1;
requestHeader.put(“X-Flag”, “TJHF”);
requestHeader.put(“Channel”, “tjhf”);
return requestHeader;
}

public interface Method {
int GET = 1;
int POST = 2;
int HEAD = 4;
}

/**
* 存储cookies
*
* @param url
* @param connection
* @throws URISyntaxException
*/
private static void readResponseCookies(URL url, HttpURLConnection connection) throws URISyntaxException {
Map<String, List<String>> headerFields = connection.getHeaderFields();
final List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
cookieManager.getCookieStore().add(url.toURI(), HttpCookie.parse(cookie).get(0));
}
}
}

private static boolean hasResponseBody(int requestMethod, int responseCode) {
return requestMethod != Method.HEAD
&& !(HttpStatus.SC_CONTINUE <= responseCode && responseCode < HttpStatus.SC_OK)
&& responseCode != HttpStatus.SC_NO_CONTENT
&& responseCode != HttpStatus.SC_NOT_MODIFIED;
}
}
自定义的信任规则管理器

package hai.com.android_test.mixed;
import javax.net.ssl.X509TrustManager;

/**
* 不安全的信任管理
*/
public class UnSafeTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}

转自:https://blog.csdn.net/u014763302/article/details/53582073
参考:https://blog.csdn.net/lwang_it/article/details/78886186
https://blog.csdn.net/u013766436/article/details/51095514
https://www.cnblogs.com/wlm-boke/p/8516046.html
https://www.cnblogs.com/DONGb/p/7844123.html

Share this:

码字很辛苦,转载请注明来自技术联盟《关于HttpUrlConnection请求网络加载证书与不加载证书的区别》

评论