背景:
一次设置用户初始密码时出现了问题: 已有用户登录时, 是前端先对用户输入的密码进行一次AES加密, 然后后端再对AES加密后的数据进行MD5存储. 此时问题就出现了, 申请账号的流程如下: 当新用户申请账号时, 无需用户输入密码, 初始化密码是后端设置好的, 也就是说需要后端先进行AES加密, 然后再进行MD5, 问题就在于后端Java实现的AES和JS实现的AES算法加密出来的结果不一致.
解决:
已知前端使用的crypto-js.js库对数据进行加密的;
后端正确做法如下:
1. 引入依赖
<!-- AES算法 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.13</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15to18</artifactId> <version>1.68</version> </dependency>
2.创建工具类
import cn.hutool.crypto.symmetric.AES; import enums.AESInfoEnum; /** * @author */ public class AESUtils { /** * 加密 * @param data 要加密的字符串 * @return 加密后的字符串 */ public static String encryption(String data, AESInfoEnum aesInfoEnum){ AES aes = new AES(aesInfoEnum.getMode(), aesInfoEnum.getPadding(), // 密钥,不可更改 (16位) aesInfoEnum.getSecret().getBytes(), // iv加盐 aesInfoEnum.getSalt().getBytes()); // 加密为16进制表示 String encryptHex = aes.encryptHex(data); return encryptHex; } /** * 解密 * @param data 要解密的字符串 * @return 解密后的字符串 */ public static String decryption(String data,AESInfoEnum aesInfoEnum){ AES aes = new AES(aesInfoEnum.getMode(), aesInfoEnum.getPadding(), // 密钥,不可更改 (16位) aesInfoEnum.getSecret().getBytes(), // iv加盐 aesInfoEnum.getSalt().getBytes()); // 加密为16进制表示 String decryptStr = aes.decryptStr(data); return decryptStr; } /*public static void main(String[] args) { //结果很完美 String encrypt = encryption("test123456",AESInfoEnum.LOGIN); System.out.println(encrypt); System.out.println(decryption(encrypt,AESInfoEnum.LOGIN)); }*/ }
3.创建枚举类
public enum AESInfoEnum { //这里的mode和padding和前端保持一致就好了 LOGIN("CBC", "PKCS7Padding","16位秘钥","16位盐值"), ; /** 模式**/ private String mode; /**填充**/ private String padding; /**加解密秘钥,不可更改 (16位)**/ private String secret; /**盐值**/ private String salt; AESInfoEnum(String mode, String padding, String secret, String salt) { this.mode = mode; this.padding = padding; this.secret = secret; this.salt = salt; } public String getMode() { return mode; } public String getPadding() { return padding; } public String getSecret() { return secret; } public String getSalt() { return salt; } }