13.5.2 HTTPS
HTTPS是一种把HTTP和SSL/TLS协议结合起来的通信方式。一些对安全性和隐私保护要求较高的网站要求通过HTTPS的方式来进行数据传输。典型的网站包括电子商务、网上银行和电子邮件服务等网站。有些网站的所有通信都是使用HTTPS进行的,而有些网站只在访问重要页面时使用HTTPS,如用户登录或进行网上支付时。在使用HTTPS的情况下,通过HTTP传输的数据都会被加密,保证了数据的安全。
配置Web服务器支持HTTPS方式并不是一件复杂的事情。很多Web服务器都提供了所需的功能,只要进行简单的配置即可。在通过HTTPS方式访问网站时,身份验证变得非常重要。进行身份验证的前提是服务器端可以提供合法有效的证书。网站的提供者通常需要向证书签发机构交纳一定的费用,才能得到有效的证书。在开发中经常会遇到自签发的证书,这些证书是由网站提供者自行创建的。在完整的证书链条中,并没有信任机构签发的证书。当通过HTTPS方式访问使用自签发证书的网站时,浏览器会给出相关的警告信息,要求用户对访问请求进行确认。如果是以程序的方式进行访问的,则访问请求会失败。
代码清单13-22中的Java类在读取HTTPS连接内容时会忽略所有与证书和主机名称验证相关的错误,总是能够读出内容。不过这种方式会带来很大的安全风险,应该谨慎使用。
代码清单13-22 忽略证书和主机名称验证的HTTPS连接
public class ReadAllHttpsClient{
public byte[]read(String urlString)throws IOException, GeneralSecurityException{
URL url=new URL(urlString);
SSLContext context=SSLContext.getInstance("TLS");
context.init(new KeyManager[]{},new TrustManager[]{new MyTrustManager()},new SecureRandom());
HttpsURLConnection connection=(HttpsURLConnection)url.openConnection();
connection.setSSLSocketFactory(context.getSocketFactory());
connection.setHostnameVerifier(new MyHostnameVerifier());
return IOUtils.toByteArray(connection.getInputStream());
}
private static class MyTrustManager implements X509TrustManager{
public void checkClientTrusted(X509Certificate[]chain, String authType)
throws CertificateException{
}
public void checkServerTrusted(X509Certificate[]chain, String authType)
throws CertificateException{
}
public X509Certificate[]getAcceptedIssuers(){
return null;
}
}
private static class MyHostnameVerifier implements HostnameVerifier{
public boolean verify(String hostname, SSLSession session){
return true;
}
}
}