密文解密流程:
先向局方申请敏感信息解密接口授权,通过后技术支持提供固定解密秘钥,根据算法规则生成动态解密秘钥。
通过标准AES加解密算法, 1中得到的秘钥,解密密文信息。
生成动态解密秘钥
网关提供固定解密秘钥,需要按照下文算法生成动态秘钥解密数据。
动态秘钥是 MD5(appId+secret+yyyyMMdd)其中 MD5加密方式是16位小写,secret为固定秘钥,yyyyMMdd为当天时间:如20190808
通过AES解密算法解密数据
AES的加密解密算法规则: AES/ECB/PKCS5Padding 128位,不要iv偏移, 字符集utf8, 输出 hex
测试加密对比示例
zhangsan
秘钥 1234567890123456
加密后的字串是:0523D5613857F67E25520C09176707E8
测试工具
测试网站:
md5加密网站: https://md5jiami.51240.com/
AES算法加密网站: http://tool.chacuo.net/cryptaes
代码示例
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
/**
* 密钥算法
*/
private static final String ALGORITHM = "AES";
/**
* 加解密算法/工作模式/填充方式
*/
private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
/**
* SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范
*/
private SecretKeySpec key;
public AESUtils(String hexKey) {
key = new SecretKeySpec(hexKey.getBytes(), ALGORITHM);
}
/**
* AES加密
* @param data
* @return
* @throws Exception
*/
public String encryptData(String data) throws Exception {
Cipher cipher = Cipher.getInstance(ALGORITHM_STR); // 创建密码器
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
return parseByte2HexStr(cipher.doFinal(data.getBytes()));
}
/**
* AES解密
* @param data
* @return
* @throws Exception
*/
public String decryptData(String data) throws Exception{
Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(hex2byte(data)));
}
private static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toLowerCase());
}
return sb.toString();
}
/**
* hex字符串 转 byte数组
* @param s
* @return
*/
private static byte[] hex2byte(String s) {
if (s.length() % 2 == 0) {
return hex2byte (s.getBytes(), 0, s.length() >> 1);
} else {
return hex2byte("0"+s);
}
}
private static byte[] hex2byte (byte[] b, int offset, int len) {
byte[] d = new byte[len];
for (int i = 0; i < len*2; i++) {
int shift = i%2 == 1 ? 0 : 4;
d[i>>1] |= Character.digit((char) b[offset+i], 16) << shift;
}
return d;
}
}
测试
String key = MD5Util.encode16("your_key");
AESUtils utils = new AESUtils(key);
String zhangsan = utils.encryptData("zhangsan");
System.out.println(zhangsan);
System.out.println(utils.decryptData(zhangsan));