高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥
在这里简单介绍下对称加密算法与非对称加密算法的区别。
对称加密算法
加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。
非对称加密算法
加密和解密用的密钥是不同的,这种加密方式是用数学上的难解问题构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal。
实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥,然后发送方和接收方用AES密钥来通信。
PKCS7 的工具类,加密之前用十六进制编过码
package com.example.administrator.standardOA.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
/**
* Created by Duqianlong on 2018/11/15.
*/
public class AESPKCS7PaddingUtils {
/**
* 算法/模式/填充
**/
private static final String CipherMode = "AES/CBC/PKCS7Padding";
// 创建密钥, 长度为128位(16bytes), 且转成字节格式
private static SecretKeySpec createKey(String key) {
byte[] data = null;
if (key == null) {
key = "";
}
StringBuffer sb = new StringBuffer(16);
sb.append(key);
while (sb.length() < 16) {
sb.append("0");
}
if (sb.length() > 16) {
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
// 创建初始化向量, 长度为16bytes, 向量的作用其实就是salt
private static IvParameterSpec createIV(String iv) {
byte[] data = null;
if (iv == null) {
iv = "";
}
StringBuffer sb = new StringBuffer(16);
sb.append(iv);
while (sb.length() < 16) {
sb.append("0");
}
if (sb.length() > 16) {
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new IvParameterSpec(data);
}
/****************************************************************************/
// 加密字节数据, 被加密的数据需要提前转化成字节格式
private static byte[] encrypt(byte[] content, String key, String iv) {
try {
SecretKeySpec secretKeySpec = createKey(key);
IvParameterSpec ivParameterSpec = createIV(iv);
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] result = cipher.doFinal(content); // 加密
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 加密字符串数据, 返回的字节数据还需转化成16进制字符串
public static String encrypt(String content, String key) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, key, "text1234");
return byte2hex(data);
}
/****************************************************************************/
// 解密字节数组
private static byte[] decrypt(byte[] content, String key) {
try {
SecretKeySpec secretKeySpec = createKey(key);
IvParameterSpec ivParameterSpec = createIV("text1234");
Cipher cipher = Cipher.getInstance(CipherMode);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] result = cipher.doFinal(content);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 解密(输出结果为字符串), 密文为16进制的字符串
public static String decrypt(String content, String password) {
byte[] data = null;
try {
data = hex2byte(content);
} catch (Exception e) {
e.printStackTrace();
}
data = decrypt(data, password);
if (data == null) return null;
String result = null;
try {
result = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/****************************************************************************/
// 字节数组转成16进制大写字符串
private static String byte2hex(byte[] b) {
String tmp = "";
StringBuffer sb = new StringBuffer(b.length * 2);
for (int n = 0; n < b.length; n++) {
tmp = (Integer.toHexString(b[n] & 0XFF));
if (tmp.length() == 1) {
sb.append("0");
}
sb.append(tmp);
}
return sb.toString().toUpperCase();
}
// 将16进制字符串转换成字节数组
private static byte[] hex2byte(String inputString) {
if (inputString == null || inputString.length() < 2) {
return new byte[0];
}
inputString = inputString.toLowerCase();
int l = inputString.length() / 2;
byte[] result = new byte[l];
for (int i = 0; i < l; ++i) {
String tmp = inputString.substring(2 * i, 2 * i + 2);
result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF);
}
return result;
}
}
PKCS5 的工具类,加密之前用Base64编过码
package com.example.administrator.standardOA.utils;
import android.util.Base64;
import com.alibaba.fastjson.JSONObject;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Duqianlong on 2018/11/15.
*/
public class AesEncryptUtils {
//可配置到Constant中,并读取配置文件注入,16位,自己定义
private static final String KEY = "xxxxxxxxxxxxxxxx";
//参数分别代表 算法名称/加密模式/数据填充方式
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* 加密
* @param content 加密的字符串
* @param encryptKey key值
* @return
* @throws Exception
*/
public static String encrypt(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
byte[] b = cipher.doFinal(content.getBytes("utf-8"));
// 采用base64算法进行转码,避免出现中文乱码
// return Base64.encodeBase64String(b);
String strBase64 = Base64.encodeToString(b , Base64.DEFAULT);
return strBase64;
}
/**
* 解密
* @param encryptStr 解密的字符串
* @param decryptKey 解密的key值
* @return
* @throws Exception
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
// 采用base64算法进行转码,避免出现中文乱码
// byte[] encryptBytes = Base64.decodeBase64(encryptStr);
byte[] encryptBytes = Base64.decode(encryptStr,Base64.DEFAULT);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
public static String encrypt(String content) throws Exception {
return encrypt(content, KEY);
}
public static String decrypt(String encryptStr) throws Exception {
return decrypt(encryptStr, KEY);
}
public static void main(String[] args) throws Exception {
Map map=new HashMap<String,String>();
map.put("loginName","jtliyajuan");
String content = JSONObject.toJSONString(map);
System.out.println("加密前:" + content);
String encrypt = encrypt(content, KEY);
System.out.println("加密后:" + encrypt);
String decrypt = decrypt(encrypt, KEY);
System.out.println("解密后:" + decrypt);
}
}
使用规则
//加密 pkcs5
public static String encryption(Map<String, String> map) {
String encrypt = "";
Gson gson = new Gson();
try {
encrypt = AesEncryptUtils.encrypt(gson.toJson(map));
} catch (Exception e) {
e.printStackTrace();
}
return encrypt;
}
//解密 pkcs5
public static String decryption(String string) {
String decrypt = "";
try {
decrypt = AesEncryptUtils.decrypt(string);
} catch (Exception e) {
e.printStackTrace();
}
return decrypt;
}
//加密
public static String pkcs7encryption(String string) {
if (!TextUtils.isEmpty(string)) {
String text1 = AESPKCS7PaddingUtils.encrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
return text1;
} else {
return "";
}
}
//解密
public static String kpcs7decryption(String string) {
if (!TextUtils.isEmpty(string)) {
String text2 = AESPKCS7PaddingUtils.decrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
return text2;
} else {
return "";
}
}