HTTP学习之使用HTTPS访问百度
2016-07-13 16:19
645 查看
序言
HTTPS是在HTTP的基础上添加了加密功能的安全办HTTP,通过在协议层使用SSL/TSL来实现数据的加密,在握手阶段,服务器会将证书和公钥传递给客户端,客户端会通过CA的公钥对证书进行认证,如果通过的话就生成一个随机数字用来做对称加密算法的秘钥,而这个秘钥会用服务器给的公钥进行加密再返回给服务器。之后客户端与服务器之间的加密就是对称加密了,因为这样性能会比公钥加密高。
更多HTTPS相关,请看Java安全通信:HTTPS与SSL。
代码
用于要使用加密功能,所以此处必须使用SSLSocket,关于其用法可以看 Java SSLSocket的使用package com.example; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public class MyHttpsClient { public static class HTTPAddress { String hostAddress; int point = 80; public HTTPAddress(String hostAddress, int point) { this.hostAddress = hostAddress; this.point = point; } } public static void main(String[] args) { //百度 String url = "https://www.baidu.com"; getStringByUrl(url); } public static final String HTTP_HEAD = "http://"; public static final String HTTPS_HEAD="https://"; public static HTTPAddress getHTTPAddress(String url) { if (url == null || url.equals("")) { return null; } String head = ""; //注意SSL的默认端口是443 int point = 443; if (url.startsWith(HTTP_HEAD)) { url = url.substring(HTTP_HEAD.length()); } if (url.startsWith(HTTPS_HEAD)) { url = url.substring(HTTPS_HEAD.length()); } //获取域名部分 head = url.split("/")[0]; //如果在url中指定端口,则获取端口 int index = head.indexOf(":"); if (index != -1) { String pointStr = head.substring(index + 1).trim(); head = head.substring(0, index); point = Integer.valueOf(pointStr); } try { //更具域名获取ip地址 String hostAddress = InetAddress.getByName(head).getHostAddress(); HTTPAddress httpAddress = new HTTPAddress(hostAddress, point); return httpAddress; } catch (UnknownHostException e) { e.printStackTrace(); } return null; } public static void getStringByUrl(String url) { try { HTTPAddress httpAddress = getHTTPAddress(url); if (httpAddress == null) { return; } SSLContext context = SSLContext.getInstance("SSL"); context.init(null,null,new SecureRandom()); SSLSocketFactory factory = context.getSocketFactory(); SSLSocket socket = (SSLSocket) factory.createSocket(httpAddress.hostAddress, httpAddress.point); // Socket socket = new Socket(httpAddress.hostAddress, httpAddress.point); OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream()); StringBuffer sb = new StringBuffer(); //拼装请求头,注意最后需要用\r\n结尾 sb.append("GET / HTTP/1.1\r\n"); sb.append("Host: " + httpAddress.hostAddress+"\r\n"); sb.append("Connection: keep-alive\r\n"); //最后的\r\n不可省略表示报文首部与报文主体的分隔 sb.append("\r\n"); osw.write(sb.toString()); osw.flush(); InputStream is = socket.getInputStream(); int count = 0; byte[] b = new byte[8192]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((count = is.read(b)) != -1) { baos.write(b, 0, count); } is.close(); baos.close(); String result = baos.toString(); //根据空行,分隔出报文首部,与报文主体 String separateStr = "\r\n\r\n"; int index = result.indexOf(separateStr); String headStr = result.substring(0, index); String contentStr = result.substring(index); System.out.print("head:" + headStr + "\n"); System.out.print("content:" + contentStr + "\n"); } catch (Exception e) { e.printStackTrace(); } } }
结果
这是返回的数据我将其中的内容部分保存为一个html文件。
用Chrome打开就是这样的,除了图片以为,都正常显示,图片是没有下载。
注意事项
1.端口
SSL一般使用的是443端口2.关于验证服务端证书
由于没有使用自己的服务端,所以直接使用默认实现就可以了。SSLContext context = SSLContext.getInstance("SSL"); context.init(null,null,new SecureRandom());
3.请求格式
我用Fiddler进行抓包,找到的请求如下,注意它的请求头在资源URL的地方只有/,在Host的地方是域名且没有端口。我把自己的请求头改成这样才成功的。相关文章推荐
- 小心服务器内存居高不下的元凶--WebAPI服务
- 运维入门
- 利用开源软件打造自己的全功能远程工具
- Linux5.9无人值守安装
- 数据中心和云未来的十二大趋势
- 虚拟化基础架构Windows 2008篇之11-WSUS服务器的安装与配置
- 用vsftp快速搭建ftp服务器
- Linux快速构建apache web服务器
- 服务器监控策略浅谈
- 书评:《算法之美( Algorithms to Live By )》
- 如何降低服务器采购成本 原理分析
- 动易2006序列号破解算法公布
- 建议的服务器分区办法
- 用ASP编写的加密和解密类
- 服务器托管六大优势分析
- Erlang实现的一个Web服务器代码实例
- 服务器技术全面解析
- 保护DNS服务器的几点方法小结
- C#递归算法之分而治之策略