对于这个问题,你可以使用一个 Map 数据结构来存储每个字段对应的加密密钥。这样,你就可以为每个字段创建一个单独的 AES 实例,而不是为整个项目创建一个。
以下是一个可能的实现:
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
@MappedTypes(String.class)
public class EncryptTypeHandler extends BaseTypeHandler<String> {
private static final String AES = "AES";
private static final String SECRET_KEY = "mySecretKey"; // 默认的密钥,你可以根据需要更改
private static final String CIPHER_MODE = "AES/ECB/PKCS5Padding"; // 默认的加密模式,你可以根据需要更改
private static final Map<String, Cipher> CIPHERS = new HashMap<>(); // 存储每个字段对应的加密实例
static {
// 初始化所有的 Cipher 实例
initCiphers();
}
private static void initCiphers() {
// 这里你可以根据需要添加更多的字段和对应的密钥
String[] fields = {"password", "mobile"}; // 你可以根据需要添加更多的字段
String[] keys = {"passwordKey", "mobileKey"}; // 你可以根据需要添加更多的密钥
for (int i = 0; i < fields.length; i++) {
try {
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
SecretKeySpec key = new SecretKeySpec(keys[i].getBytes(), AES);
cipher.init(Cipher.ENCRYPT_MODE, key);
CIPHERS.put(fields[i], cipher);
} catch (Exception e) {
throw new RuntimeException("Failed to initialize cipher for field " + fields[i], e);
}
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, encrypt(parameter, CIPHERS.get(parameter))); // 使用对应字段的 Cipher 进行加密
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return decrypt(rs.getString(columnName), CIPHERS.get(columnName)); // 使用对应字段的 Cipher 进行解密
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return decrypt(rs.getString(columnIndex), CIPHERS.get(columnIndex)); // 使用对应字段的 Cipher 进行解密
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return decrypt(cs.getString(columnIndex), CIPHERS.get(columnIndex)); // 使用对应字段的 Cipher 进行解密
}
}