近期由于公司的工作需要,需要将原有的http接口切换到https,故做了如下学习和整理。本文先简要说明https协议原理,然后https协议在浏览器和App的实践两方面进行讲述;
一、https协议原理
1.要理解https是什么,我们必须应该理解如下几个关键词,和它们之间的关系:
http:超文本传输协议,广泛用于从WWW服务器传输超文本到本地浏览器的传输协议;
SSL/TLS:最广泛的密码通信方案,综合运用了对称密码、消息认证码、公钥密码、数字签名、伪随机数生成密码等密码技术;
https:在SSL/TLS之上承载HTTP,将两种协议进行叠加;
2.在继续讲解https之前,我们得先了解下几个密码学套件,对于比较好理解的对称密码和非对称密码就不进行详细的讲解了:
单项散列函数:根据任意长度的消息计算出固定长度的散列值,来确定文件的完整性;
消息认证码:是一种密钥相关联的单向散列函数。要计算MAC必须持有共享秘钥,消息变化MAC值就会不一致,故验证身份和完整性;
数字签名:反用密钥对,使用自己私钥加密生成签名,验证方用你的公钥能解密即可验证加密方是你,故能验证身份和完整性;
公钥证书:认证机构通过电话、邮件或本人确认后,使用机构的私钥对你的公钥进行签名,保证了你的公钥的正确性;
3.完成基本密码套件的学习,接下来我们继续介绍https。由上可知https的核心在于SSL/TLS,让主要解决了如下接个问题:
机密性:信息传输过程中的被第三方窃听—采用对称密码加密,伪随机数生成器密钥,公钥密码或Diffe-Hellman进行公钥交换;
完整性:信息传输过程中被中间人篡改—采用单向散列函的消息认证码进行完整性验证;
认证性:信息传输的对方身份是否合法—对公钥加上数字签名所生成的证书,对通信对象进行认证;
4.在https的进行通信的过程中,它是如何有序的运用上面的密码学套件的呢?如下:
该部分是基于TLS1.0进行说明,TLS协议是由“TLS记录协议”和“TLS握手协议”这两层协议叠加而成:
1.握手协议:除加密之外的各种工作,分为4个子协议:握手协议、密码规格变更协议、警告协议和应用数据协议;
握手子协议:负责在客户端和服务器之间协商决定密码算法和共享秘钥;
密码规格变更协议:负责向通信对象传达变更密码方式的信号;
警告协议:负责在发生错误的时候将错误传达给对方;
应用数据协议:将TLS上面承载的应用数据传达给通信对象的协议;
2.记录协议:位于TLS握手协议的下层,负责使用对称密码对消息进行压缩、加密以及数据的认证;
消息被分割成多个较短的片段,然后对每个片段进行压缩;
压缩片段会被加上消息认证码,保证完整性,并进行数据的认证,可以识别出篡改。为了防止重放攻击,在计算消息认证码时加上了片段的编号;
经过压缩的片段在加上消息认证码会一起通过对称密码进行加密;
经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据;
经过以上的大概讲解,相信大家对https有了更深入的认识,并且也能更好的理解为什么在实践https的时候要生成各种密钥和信任库了。
二、https协议实践
理解上面的相关原理后,我们就开始实现HttpsServlet来模拟简单登录接口,然后通过浏览器和app的访问该https接口;
1.服务端http实现
我们首先实现服务端http协议的get和post通信,项目的结构和主要实现代码如下:
HttpsServlet.java:
一、https协议原理
1.要理解https是什么,我们必须应该理解如下几个关键词,和它们之间的关系:
http:超文本传输协议,广泛用于从WWW服务器传输超文本到本地浏览器的传输协议;
SSL/TLS:最广泛的密码通信方案,综合运用了对称密码、消息认证码、公钥密码、数字签名、伪随机数生成密码等密码技术;
https:在SSL/TLS之上承载HTTP,将两种协议进行叠加;
2.在继续讲解https之前,我们得先了解下几个密码学套件,对于比较好理解的对称密码和非对称密码就不进行详细的讲解了:
单项散列函数:根据任意长度的消息计算出固定长度的散列值,来确定文件的完整性;
消息认证码:是一种密钥相关联的单向散列函数。要计算MAC必须持有共享秘钥,消息变化MAC值就会不一致,故验证身份和完整性;
数字签名:反用密钥对,使用自己私钥加密生成签名,验证方用你的公钥能解密即可验证加密方是你,故能验证身份和完整性;
公钥证书:认证机构通过电话、邮件或本人确认后,使用机构的私钥对你的公钥进行签名,保证了你的公钥的正确性;
3.完成基本密码套件的学习,接下来我们继续介绍https。由上可知https的核心在于SSL/TLS,让主要解决了如下接个问题:
机密性:信息传输过程中的被第三方窃听—采用对称密码加密,伪随机数生成器密钥,公钥密码或Diffe-Hellman进行公钥交换;
完整性:信息传输过程中被中间人篡改—采用单向散列函的消息认证码进行完整性验证;
认证性:信息传输的对方身份是否合法—对公钥加上数字签名所生成的证书,对通信对象进行认证;
4.在https的进行通信的过程中,它是如何有序的运用上面的密码学套件的呢?如下:
该部分是基于TLS1.0进行说明,TLS协议是由“TLS记录协议”和“TLS握手协议”这两层协议叠加而成:
1.握手协议:除加密之外的各种工作,分为4个子协议:握手协议、密码规格变更协议、警告协议和应用数据协议;
握手子协议:负责在客户端和服务器之间协商决定密码算法和共享秘钥;
密码规格变更协议:负责向通信对象传达变更密码方式的信号;
警告协议:负责在发生错误的时候将错误传达给对方;
应用数据协议:将TLS上面承载的应用数据传达给通信对象的协议;
2.记录协议:位于TLS握手协议的下层,负责使用对称密码对消息进行压缩、加密以及数据的认证;
消息被分割成多个较短的片段,然后对每个片段进行压缩;
压缩片段会被加上消息认证码,保证完整性,并进行数据的认证,可以识别出篡改。为了防止重放攻击,在计算消息认证码时加上了片段的编号;
经过压缩的片段在加上消息认证码会一起通过对称密码进行加密;
经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数据;
经过以上的大概讲解,相信大家对https有了更深入的认识,并且也能更好的理解为什么在实践https的时候要生成各种密钥和信任库了。
二、https协议实践
理解上面的相关原理后,我们就开始实现HttpsServlet来模拟简单登录接口,然后通过浏览器和app的访问该https接口;
1.服务端http实现
我们首先实现服务端http协议的get和post通信,项目的结构和主要实现代码如下:
HttpsServlet.java:
public class HttpsServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost");
doLoginRequest(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet");
doLoginRequest(req, resp);
}
//实现简单的登录逻辑
private void doLoginRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException {
PrintStream printStream = new PrintStream(resp.getOutputStream());
HttpsResponse httpsResponse = new HttpsResponse();
String userName = req.getParameter("userName");
String passWord = req.getParameter("passWord");
if ("123".equals(userName) && "123".equals(passWord)) {
httpsResponse.setCode("000");
httpsResponse.setMessage("login success!");
} else {
httpsResponse.setCode("004");
httpsResponse.setMessage("login faild!");
}
printStream.println(JSON.toJSONString(httpsResponse));
}
}
web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>HttpsServlet</servlet-name>
<servlet-class>main.com.chengxiang.servlet.HttpsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpsServlet</servlet-name>
<url-pattern>/HttpsServlet</url-pattern>
</servlet-mapping>
</web-app>
实现客户端登录的get和post请求,项目目录结构如下:
NextActivity.java:
public class NextActivity extends AppCompatActivity {
private EditText userNameEditText;
private EditText passWorldEditText;
private Button loginButton;
private TextView responseTextView;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
Bundle bundle = msg.getData();
HttpsResponse httpsResponse = (HttpsResponse) bundle.getSerializable("result");
responseTextView.setText(httpsResponse.toString());
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next)