android 访问https服务器

释放双眼,带上耳机,听听看~!

之前,我讲了如何让tomcat支持https访问,当时浏览器通过https:localhost:8443即可访问tomcat。可是android此时如何访问已经搭建好的tomcat的https了?我在网上找了很多资料,发现还是有问题,后来自己改了一些,终于是做出来了。

1.搭建tomcat的https服务器。

这个,我之前的博客已经讲过,所有不在细讲了。

 

2.将搭建tomcat服务器时生成的server.cer证书放在android的assets目录下,应为客户端用https访问时需要检测服务器的证书是否符合要求。

 

3.编写一个类继承X509TrustManager,X509TrustManager是证书信任管理器类,我们可以自己实现该接口,让它信任我们指定的证书。

自己实现了信任管理器类,如何使用呢?类HttpsURLConnection似乎并没有提供方法设置信任管理器。其实,HttpsURLConnection通过SSLSocket来建立与HTTPS的安全连接,SSLSocket对象是由SSLSocketFactory生成的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)设置它使用的SSLSocketFactory对象。SSLSocketFactory通过SSLContext对象来获得,在初始化SSLContext对象时,可指定信任管理器对象。

public class TrustAllCertsManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// Do nothing -> accept any certificates
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
// Do nothing -> accept any certificates
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}

 

4.编写一个类实现HostnameVerifier接口,此类是用于主机名验证的基接口。

在握手期间,如果 URL 的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。

策略可以是基于证书的或依赖于其他验证方案。

当验证 URL 主机名使用的默认规则失败时使用这些回调。

public class VerifyEverythingHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}

此时,我设置对所有主机都可以访问。

5.实例化服务器的证书。

private TrustManager[] createTrustManager() {
BufferedInputStream cerInputStream = null;
try {
// 获取客户端存放的服务器公钥证书
cerInputStream = new BufferedInputStream(getAssets().open("server.cer"));
// 根据公钥证书生成Certificate对象
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate ca = cf.generateCertificate(cerInputStream);
Log.e("TAG", "ca=" + ((X509Certificate) ca).getSubjectDN());
// 生成包含当前CA证书的keystore
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// 使用包含指定CA证书的keystore生成TrustManager[]数组
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
return tmf.getTrustManagers();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} finally {
if (cerInputStream != null) {
try {
cerInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}

 

上面的代码比较固定,其中server.cer是配置tomcat时的服务器证书。具体我也不是很清楚,可以去百度找一下。

 

6.具体实现https请求。

 private void httpsRequest(){
String name="健康科技";
String pass="123456";
TrustManager[] trustManager = createTrustManager();
//        TrustManager[] trustManager = new TrustManager[]{new TrustAllCertsManager()};
SSLContext sslContext = null;
if (trustManager == null) {
Log.e("TAG", "tmf create failed!");
return;
}
try {
sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManager, new java.security.SecureRandom());
} catch (NoSuchAlgorithmException e) {
// do nothing
}catch (KeyManagementException e) {
// do nothing
}
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection httpsURLConnection = null;
BufferedReader reader = null;
URL url = null;
try {
url = new URL("https://192.168.1.190:8443/MyWeb/HttpServlet");
httpsURLConnection = (HttpsURLConnection) url.openConnection();
httpsURLConnection.setHostnameVerifier(new VerifyEverythingHostnameVerifier());
httpsURLConnection.setConnectTimeout(5000);
httpsURLConnection.setDoInput(true);
httpsURLConnection.setUseCaches(false);
//将用户名和密码放入HashMap中
Map<String,String> params=new HashMap<String,String>();
params.put("userName", name);
params.put("passWord", pass);
StringBuffer stringBuffer = new StringBuffer();        //存储封装好的请求体信息
try {
for(Map.Entry<String, String> entry : params.entrySet()) {
stringBuffer.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), "UTF-8"))
.append("&");
}
stringBuffer.deleteCharAt(stringBuffer.length() - 1);    //删除最后的一个"&"
} catch (Exception e) {
e.printStackTrace();
}
byte[] data=stringBuffer.toString().getBytes();
httpsURLConnection.setRequestMethod("POST");   //设置请求为POST
httpsURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpsURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));
httpsURLConnection.connect();
OutputStream outputStream = httpsURLConnection.getOutputStream();
outputStream.write(data);
reader = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sBuilder.append(line);
}
Log.e("TAG", "Wiki content=" + sBuilder.toString());
final String s=sBuilder.toString();
runOnUiThread(new Runnable() {
@Override
public void run() {
mTextView.setText(s.toString());
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

 

到这来,客户端就可以做https请求了,不过服务器的tomcat需要自己写一个简单的HttpServlet,这个很简单,自己完全可以百度。

 

人已赞赏
Android文章

Android开发GridView的全选与反选

2020-3-13 6:25:04

Android文章

Android开发listview异步加载图片

2020-3-13 12:23:30

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索