1.1 为什么要对API接口进行加密?
因为http协议是明文传输,它是不够安全的,比如进行get请求的时候,请求参数会直接附加在URL后边,即使是post请求其实也是不够安全的,如果用户连接了不安全的网络,这个时候黑客可能可以通过抓包工具直接获取请求信息,并且黑客可能对请求参数进行非法篡改,所以API接口加密就显得至关重要了!
1.2 常见的接口加密方式有哪些?
使用https协议(相比较与http协议,https协议加入了ssl证书,并且https是基于ssl的密文传输方式)、参数加密使用对称加密或非对称加密。
1.3 URL特殊字符转码
1.3.1 什么是URL特殊字符?使用这些字符在请求参数中会照成什么问题?
比如\、?、+、#等一些特殊字符都是URL特殊字符,当这些字符用在请求参数中,可能会导致后端获取到的请求参数与原始值不一致。 如上图中,请求参数userName是1+1,后端参数接收实际上为1 1(1空格1)。
1.3.2 在Java中如何实现URL特殊字符转码与解码?
在Java中要实现URL的转码特别简单,可以直接使用javax.net包中的,URLEncoder进行编码,使用URLDeCoder可以实现URL特殊编码的解码,当然也可以借助其他第三方的解码类库。
1.3.2.1 使用javax.net.URLEncoder进行URL特殊字符编码
@Test
public void urlEncoderTest(){
String userName="xiao+ming";
System.out.println("编码前:"+userName);
try {
userName=URLEncoder.encode(userName,"utf-8");
System.out.println("编码后:"+userName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace(); }
}
控制台输出结果: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200628151331279.png)
1.3.2.2 使用javax.net.URLDecoder进行URL特殊字符解码
public void urlEncoderTest(){
String userName="xiao+ming";
System.out.println("编码前:"+userName);
try {
userName=URLEncoder.encode(userName,"utf-8");
System.out.println("编码后:"+userName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
userName= URLDecoder.decode(userName,"utf-8");
System.out.println("解码后:"+userName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
控制台打印结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200628151433306.png)
1.4 什么是对称加密?
对称加密指的是,加密与解密的密钥是一致的,也就是说通过什么密钥进行加密就使用什么密钥解密,常见的对称加密算法有AES、DES。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200628151444299.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMTk5MDE2,size_16,color_FFFFFF,t_70)
1.4.1 对称加密的使用场景
服务端与服务端的通信可以采用对称加密,因为这种场景相对安全,不会将密钥保存在客户端所以其他人无法对数据进行解密,也就无法非法获取数据。
1.4.2 对称加密的缺点
不适合用于,客户端与服务器端交互的加密,因为他人可能通过反编译客户端源码的方式获取到加密密钥。
1.5 什么是非对称加密?
非对称加密,指的就是加密使用的密钥与解密使用的密钥是不一致的,也就是我们常说的公钥与私钥,非对称加密的典型算法是RSA。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200628151454475.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzMTk5MDE2,size_16,color_FFFFFF,t_70)
1.5.1 通过工具类生成公钥和私钥
package com.muzili.demo.demo0628.util;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA加密,支持分片加密
*
* BCD码(Binary-Coded Decimal)亦称二进码十进数或二-十进制代码。
* 用4位二进制数来表示1位十进制数中的0~9这10个数码。
* 是一种二进制的数字编码形式,用二进制编码的十进制代码。
* 注:日常所说的BCD码大都是指8421BCD码形式
* @author muzili
*
*/
public class RSAUtil {
/** 指定加密算法为RSA */
private static String ALGORITHM = "RSA";
/** 指定key的大小 */
private static int KEYSIZE = 1024;
/** 指定公钥存放文件 */
private static String PUBLIC_KEY_FILE = "PublicKey.key";
/** 指定私钥存放文件 */
private static String PRIVATE_KEY_FILE = "PrivateKey.key";
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 生成密钥对
*/
public static void generateKeyPair() throws Exception {
if (getpublickey() == null
|