区别
HTTP 协议传输的数据都是未加密的, 也就是明文的, 因此使用 HTTP 协议传输隐私信息非常不安全, 为了保证这些隐私数据能加密传输, 于是网景公司设计了 SSL(Secure Sockets Layer)协议用于对 HTTP 协议传输的数据进行加密, 从而就诞生了 HTTPS.
HTTPS 和 HTTP 的区别主要如下:
1,https 协议需要到 ca 申请证书, 一般免费证书较少, 因而需要一定费用.
2,http 是超文本传输协议, 信息是明文传输, https 则是具有安全性的 ssl 加密传输协议.
3,http 和 https 使用的是完全不同的连接方式, 用的端口也不一样, 前者是 80, 后者是 443.
4,http 的连接很简单, 是无状态的; HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输, 身份认证的网络协议, 比 http 协议安全.
HTTPS 工作原理, 工作流程
1. 客户端发起请求
2. 服务端配置公钥私钥. 如果是使用购买的证书, 把公钥告诉客户端.
3. 服务端把当前此次请求的证书 (公钥) 传送过来
image.png
4. 客户端进行证书解析
客户端会验证公钥是否有效. 如果没有问题, 就回生成一个随机值, 并对其进行加密,(这个随机值其实就是对称加密的私钥)
5. 将加密后的随机值等加密信息传给服务端
6. 服务端解密信息
服务端用私钥解密后, 得到了客户端传过来的随机值(私钥), 然后把内容进行对称加密.
7. 通信. 因为客户端跟服务端都有对称加密的秘钥. 所以 ok 了.
加密过程中的对称加密非对称加密
首先用的是非对称加密. 把公钥给客户端, 私钥在服务端. 客户端用公钥验证通过后, 会生成私钥进行对称加密. 然后传给后台.
为什么这么做呢.
对称加密加密与解密使用的是同样的密钥, 所以速度快, 但由于需要将密钥在网络传输, 所以安全性不高.
非对称加密使用了一对密钥, 公钥与私钥, 所以安全性高, 但加密与解密速度慢.
所以第一次用公钥私钥验证. 没问题之后, 在用对称加密. 这样既安全又高效.
Android 证书配置. 结合流程看一下
- /**
- * 使用购买的证书
- */
- public static SSLSocketFactory getDefSSLSocketFactory() {
- try {
- // 初始化 SSLContext
- SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);
- final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- }
- // 验证服务端证书的公钥
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
- if (chain == null) {
- throw new IllegalArgumentException("checkServerTrusted:x509Certificate array isnull");
- }
- if (!(chain.length> 0)) {
- throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");
- }
- if (!(!TextUtils.isEmpty(authType) && authType.toUpperCase().contains("RSA"))) {
- throw new CertificateException("checkServerTrusted: AuthType is not RSA");
- }
- // Hack ahead: BigInteger and toString(). We know a DER encoded Public Key begins
- // with 0×30 (ASN.1 SEQUENCE and CONSTRUCTED), so there is no leading 0×00 to drop.
- RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();
- /* signum:1 表示是正数; radix:16 表示字节数组转 16 进制 */
- String encoded = new BigInteger(1 /* positive */, pubkey.getEncoded()).toString(16);
- final boolean expected = PUB_KEY.equalsIgnoreCase(encoded); // 验证服务端证书的公钥
- if (!expected) {
- throw new CertificateException("checkServerTrusted: got error public key:" + encoded);
- }
- }
- @Override
- public java.security.cert.X509Certificate[] getAcceptedIssuers() {
- return new java.security.cert.X509Certificate[0];
- }
- }};
- // 将随机数等加密之后传给服务端.
- sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
- return sslContext.getSocketFactory();
- } // 省略各种异常处理, 请自行添加
- catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- } catch (KeyManagementException e) {
- e.printStackTrace();
- }
- return null;
- }
图中的方法是验证服务端购买的证书. 如果是信任所有证书的. 这三个重写的方法不需要做操作. 直接用默认即可.
参考感谢
详细解析 HTTP 与 HTTPS 的区别 https://juejin.im/entry/58d7635e5c497d0057fae036
非对称加密和对称加密的区别 https://blog.csdn.net/u013320868/article/details/54090295
如有错误. 还望指正, 非常感谢.
来源: http://www.jianshu.com/p/7a40e874f6c2