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;

}

}

}