做网络框架,势必要与http请求打交道,那么加密策略也是各大公司必不可少的部分。这篇文章我来总结下我接触过的加密算法和策略。
一、基础
首先http协议本身存在安全性问题,主要为如下几点:
-
数据隐私性
:通信使用明文、内容可能被窃取。 -
数据完整性
:无法证明报文完整性,内容可能遭篡改。 -
身份认证
:不验证通信方身份,可能遭遇伪装。
因此要解决这些问题,就引入了加密。那么目前加密主要分两大类:
-
自定义
:说白了就是跟服务端约定好加解密方案和规则,对请求和响应进行加密,防止明文裸奔,同时做好完整性认证和身份认证。 -
三方
:用https,https在http基础上增加了ssl加密层,对传输数据帮你做好了加解密,通过购买证书、添加证书记录、颁发证书后上传来完成域名https化就行。客户端只需要配置下网络库去支持https,目前volley和okhttp都支持https。
二、加密算法
好,那么不管是自定义还是三方方案,都会用到加密算法,那么基本加密算法还是有必要了解下。
2.1 签名和加密
A向B发送信息,数据签名是让B确认信息是A发送的,不是别人。而数据加密保证数据不能被除B之外的其他人获取到。
2.2 加密算法
1)对称性加密算法
加密和解密使用同一个密钥(私钥),信息接收双方都需事先知道密匙和加解密算法。
AES 高级加密标准,又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
-
ECB模式 (Electronic Codebook Book)
将整个明文分成若干段相同的小段,然后对每一小段进行加密。 -
CBC模式(Cipher Block Chaining)
先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
优点:加解密速度快、效率高。
缺点:对称加密时,都需要使用其他人不知道的唯一秘钥,密钥数量巨大,管理和分发非常困难,秘钥一旦泄露,加密信息就不安全了。
作用:对传输明文加解密。
2)非对称加密算法
加密和解密所使用的不是同一个密钥,通常有两个密钥,称为"公钥"和"私钥",它们两个必需配对使用,否则不能打开加密文件。双方分别生成公私钥,公钥给对方,私钥自己保留。拿对方的公钥向对方发送加密信息,对方拿私钥解密。
RSA 目前主流的非对称加密算法。
优点:秘钥管理方便,安全性高。
缺点:加解密过程复杂,耗时长,只适合对少量数据加密。
数据加密:任何发送方都可以用接收方的公钥加密,接收方用对应的私钥解密。
数据签名:用发送方的私钥加密,任何接收方都可以用发送方公钥解密。
3)散列算法/哈希算法
一种单向加密算法,过程不可逆。
MD5 信息摘要算法。把任意数据转换为定长(或限制长度)的数据,
SHA1 也是一种哈希算法,与md5类似。SHA1摘要比md5长32位,安全性更好,但是运算步骤要多一些,所以慢一些。
作用:进行一致性验证、数字签名、安全访问认证。
4)其他算法
严格意义上不算加密。
Base64 一种编码方式,用来将非ASCII字符的数据转换成ASCII字符的一种转换算法。
作用:便于网络传输。
算法基本分这么四类,每一类都包含但不限于这么几种,每类我只例举了目前最为主流的方案,最个基本介绍。
三、加密策略
那么,介绍完加密算法,接下来谈谈目前主要使用的加密策略。
3.1 RSA+SHA1
用SHA算法进行签名,用RSA算法进行加密。
加密流程:
1)利用私钥将请求参数进行 SHA1withRSA 签名即可。
/**
* 进行sha1 Rsa算法签名
* @param str
* @param privateKey
* @return
*/
public static byte[] sha1WithRsa(String str, PrivateKey privateKey) {
try {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(str.getBytes());
return signature.sign();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}
2)加密完成开始打包参数。
主要玩的是这个类:/Android/sdk/sources/android-27/java/security/Signature.java
3.2 RSA+AES
使用RSA来首先传输AES的密钥给对方,然后再使用AES来进行加密通讯。
加密流程:
1)将请求参数进行AES加密。
public static byte[] encryptByAes(String data, String pass, String init,
String mode) throws Exception {
String transformation;
//选择CBC or ECB模式
if (mode.equals(Constant.ECODE_METHOD)) {
transformation = Constant.AES_TRANSFORMATION_CBC;
} else {
transformation = Constant.AES_TRANSFORMATION_ECB;
}
try {
Cipher cipher = Cipher.getInstance(transformation);
int blockSize = cipher.getBlockSize();
...
// 将随机生成的密码变成AES算法的私钥
SecretKeySpec keyspec = new SecretKeySpec(hexString2Bytes(pass),
"AES");
// ECB don't need ivspec
IvParameterSpec ivspec = new IvParameterSpec(init.getBytes());
if (mode.equals(Constant.ECODE_METHOD)) {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
} else {
cipher.init(Cipher.ENCRYPT_MODE, keyspec);
}
byte[] encrypted = cipher.doFinal(plaintext);
return encrypted;
} catch (Exception e) {
e.printStackTrace();
return new byte[0];
}
}
2)利用私钥将AES加密后的结果进行RSA加密。
/**
* 进行Rsa算法加密
* @param data 需要加密的数据
* @param privateKey 加密所需要的私钥
* @return
*/
public static byte[] encryptByRsa(String data, PrivateKey privateKey) {
try
Cipher cipher = Cipher.getInstance(Constant.RSA_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptData = cipher.doFinal(data.getBytes());
return encryptData;
} catch (Exception e) {
e.printStackTrace();
return new byte[0];
}
}
3)加密完成开始打包参数。
主要玩的是这个类:Android/sdk/sources/android-27/javax/crypto/Cipher.java
公司保密性原因,具体细节不便过多透露,这里了解个大概策略就行,具体加解密代码网上应该能搜到一大堆。
3.3 数据签名
这种方案就纯跟服务端去自定义你们觉得合适的加密方式来满足明文保密、明文完整性验证和身份验证的需要。
3.4 Https
HTTPS = HTTP+SSL(TLS)。
原本HTTP和TCP/UDP直接通信,而加了SSL后,就变成HTTP先和SSL通信,再由SSL和TCP/UDP通信。
HTTPS和HTTP的主要区别:
- https协议需要到ca申请证书,一般免费证书较少,需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
说白了,https就是在http协议层面帮你做了加密。
优点:加密传输、身份认证、安全性高。
缺点:
- HTTPS协议握手阶段比较费时,会使页面的加载时间延长,同时增加耗电;(这个没验证过具体程度)
- 证书需要一定费用。
- 加密和证书都依赖第三方,存在风险。
Https也是对称加密和非对称加密结合的方式。
加解密过程:
1)浏览器使用Https的URL访问服务器,建立SSL链接。
2)服务器收到SSL链接,发送非对称加密的公钥A返回给浏览器
3)浏览器生成随机数,作为对称加密的密钥B
4)浏览器使用公钥A,对自己生成的密钥B进行加密,得到密钥C
5)浏览器将密钥C,发送给服务器。
6)服务器用私钥D对接受的密钥C进行解密,得到对称加密钥B。
7)浏览器和服务器之间可以用密钥B作为对称加密密钥进行通信。
四、个人总结
一般来说,很多公司直接使用的https,当然也可以根据自身业务和环境选择一种或者多种加密策略。
下面是我搞过的一套完整方案,不过多介绍,点到为止:
网友评论