摘要
由于业务需求,对接一家第三方服务商,接口报文是使用AES GCM算法加密的字节流数据
算法简介
AES 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
解密异常问题分析
在对接联调中解密报文一直有问题,由于一些外部因素不能直接与对方技术沟通交流,走了一些弯路,下面是问题分析
- 开始是将对方的authTag数据当做秘钥盐使用,发现解密失败,见加解密encrypt/decrypt方法
- 失败后改为使用附加数据验证方式见encrypt2/decrypt2方法,此时还是解密失败
- 此时怀疑是拿到报文字节流可能有特殊字符被防火墙拦截了,故找厂商线下拿到密文,可还是解密失败
- 开始怀疑对方不是使用的常规方式加密,再经过一道道信息传递,最终知道传输数据只是密文的一部分,需要与authTag拼接一起才是完整密文,加解密算法见encryptForPartner/decryptForPartner,此时解密线下拿到密文,终于ok了
- 接下来通过接口解密发现还是不行,有点疑惑???
- 经过仔细分析接口代码,发现有可能出问题的地方,是将接收到字节流转换为字符串了,用密文文件测试发现果然是这个问题;原因是密文字节流转字符串后出现不可逆操作,遂最终直接操作字节流问题解决
示例代码
private static Logger logger = LoggerFactory.getLogger(AESUtil.class);
private static final String KEY_ALGORITHM = "AES";
/** 默认的加密算法 */
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/GCM/PKCS5Padding";
/** must be one of {128, 120, 112, 104, 96} */
private static final int TAG_LENGTH_BIT = 128;
/**
* Password derived AES 256 bits secret key
*
* @param password
* @param salt
* @return
* @throws Exception