对称加密:
对称加密是最快速、最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key)。
AES加密:
高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具有以下几个特点:
1、最常用的对称加密算法
2、密钥建立时间短、灵敏性好、内存需求低
3、实际使用中,使用工作模式为CTR(最好用BC去实现),此工作模式需要引入IV参数(16位的字节数组)
4、密钥长度128/192/256,其中192与256需要配置无政策限制权限文件(JDK6)
5、填充模式最常用的两种PKCS5Padding和PKCS7Padding,其中后者只有BC独有。
6、加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。
简叙和非对称加密场景的差异对称加密:适合经常发送数据的场合非对称加密:加密和解密用的密钥是不同的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。
非对称加密:加密和解密用的密钥是不同的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。
具体的加密流程如下图:
image
生成AES秘钥工具类:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public void make() throws NoSuchAlgorithmException {
BASE64Encoder base64Encoder = new BASE64Encoder();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
System.out.println("AES: " + base64Encoder.encode(raw).replaceAll("\r|\n", ""));
}
AES加解密工具类:
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
public class EncryptUtil {
public static final String key = "秘钥";
/**
* 密钥算法
*/
public static final String KEY_ALGORITHM = "AES";
/**
* 加密/解密算法 / 工作模式 / 填充方式
*/
public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* 转换密钥
*
* @param key 二进制密钥
* @return Key 密钥
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
// 实例化AES密钥材料
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 还原密钥
Key k = toKey(key);
/*
* 实例化
* 使用PKCS7Padding填充方式,按如下方式实现
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
/**
* 加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 还原密钥
Key k = toKey(key);
/*
* 实例化
* 使用PKCS7Padding填充方式,按如下方式实现
* Cipher.getInstance(CIPHER_ALGORITHM, "BC");
*/
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// 初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, k);
// 执行操作
return cipher.doFinal(data);
}
public static String encrypt(String keyStr,String data,String charset)throws Exception{
byte[] keyBytes = Base64.decodeBase64(keyStr.getBytes(charset));
byte[]dataBytes=data.getBytes(charset);
byte[]encryptedBytes=encrypt(dataBytes,keyBytes);
return new String(Base64.encodeBase64(encryptedBytes), charset);
}
public static String decrypt(String keyStr,String encryptedData,String charset)throws Exception{
BASE64Encoder base64Encoder = new BASE64Encoder();
byte[] keyBytes = Base64.decodeBase64(keyStr.getBytes(charset));
byte[] encryptedDataBytes = Base64.decodeBase64(encryptedData.getBytes(charset));
byte[] dataBytes = decrypt(encryptedDataBytes, keyBytes);
return new String(dataBytes, charset);
}
}
验证:
public static void main(String[] args) throws Exception {
Map inMap = RMap.asMap("phone","14700000000");
String s = JSON.toJSONString(inMap);
String aesData = EncryptUtil.encrypt(EncryptUtil.key,s,"utf-8");
System.out.println("data 加密后参数:" + aesData);
String decryptedData = EncryptUtil.decrypt(EncryptUtil.key,aesData,"utf-8");
System.out.println("data 解密后的参数:" + decryptedData);
}
//输出结果:
data 加密后参数:knlYATMUWUBWbliaF+hIMFVwy331bDyIRQPGsbHU4VI=
data 解密后的参数:{"phone":"14700000000"}
网友评论