一、前言
web系统数据库中保存的公民信息不允许明文存储,比如手机号,身份证号,收货地址等。
二、处理方式
数据库中密文存储,web通过注解的方式对数据加解密处理,下面是处理方法
1、编写接口
public interface EncryptDecryptInterface {
public <T> T encryptSelf();
public <T> T decryptSelf();
public <T> List<T> encryptSelfList(List<T> c);
public <T> List<T> decryptSelfList(List<T> c);
}
public interface EncryptDecryptInterface {
public <T> T encryptSelf();
public <T> T decryptSelf();
public <T> List<T> encryptSelfList(List<T> c);
public <T> List<T> decryptSelfList(List<T> c);
}
2、接口实现
@Data
public class BaseEntity implements Serializable, Cloneable, EncryptDecryptInterface {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 数据归属码
*/
private String belongCode;
/**
* 数据归属名称
*/
private String belongName;
/**
* 数据类型
*/
private String dataType;
@SuppressWarnings("unchecked")
@Override
public <T> T encryptSelf() {
toCommaint(this, EncryptFiled.class, "Encrypt");
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public <T> T decryptSelf() {
toCommaint(this, DecryptFiled.class, "Decrypt");
return (T) this;
}
@Override
public <T> List<T> encryptSelfList(List<T> l) {
for (T t : l) {
toCommaint(t, EncryptFiled.class, "Encrypt");
}
return l;
}
@Override
public <T> List<T> decryptSelfList(List<T> l) {
for (T t : l) {
toCommaint(t, DecryptFiled.class, "Decrypt");
}
return l;
}
/**
* 描述:转换方法
*
* @auter dongjing.chen
* @create 2022/4/20 16:31
*/
@SuppressWarnings("unchecked")
public <T> T toCommaint(T t, @SuppressWarnings("rawtypes") Class c, String type) {
Field[] declaredFields = t.getClass().getDeclaredFields();
try {
if (declaredFields != null && declaredFields.length > 0) {
for (Field field : declaredFields) {
if (field.isAnnotationPresent(c) && field.getType().toString().endsWith("String")) {
field.setAccessible(true);
String fieldValue = (String) field.get(t);
if (StringUtils.isNotEmpty(fieldValue)) {
if (type.equals("Decrypt")) {
fieldValue = PGSQLUtils.decrypt(fieldValue);
} else if (type.equals("Encrypt")) {
fieldValue = PGSQLUtils.encrypt(fieldValue);
}
field.set(t, fieldValue);
}
}
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return t;
}
}
@Data
public class BaseEntity implements Serializable, Cloneable, EncryptDecryptInterface {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 数据归属码
*/
private String belongCode;
/**
* 数据归属名称
*/
private String belongName;
/**
* 数据类型
*/
private String dataType;
@SuppressWarnings("unchecked")
@Override
public <T> T encryptSelf() {
toCommaint(this, EncryptFiled.class, "Encrypt");
return (T) this;
}
@SuppressWarnings("unchecked")
@Override
public <T> T decryptSelf() {
toCommaint(this, DecryptFiled.class, "Decrypt");
return (T) this;
}
@Override
public <T> List<T> encryptSelfList(List<T> l) {
for (T t : l) {
toCommaint(t, EncryptFiled.class, "Encrypt");
}
return l;
}
@Override
public <T> List<T> decryptSelfList(List<T> l) {
for (T t : l) {
toCommaint(t, DecryptFiled.class, "Decrypt");
}
return l;
}
/**
* 描述:转换方法
*
* @auter dongjing.chen
* @create 2022/4/20 16:31
*/
@SuppressWarnings("unchecked")
public <T> T toCommaint(T t, @SuppressWarnings("rawtypes") Class c, String type) {
Field[] declaredFields = t.getClass().getDeclaredFields();
try {
if (declaredFields != null && declaredFields.length > 0) {
for (Field field : declaredFields) {
if (field.isAnnotationPresent(c) && field.getType().toString().endsWith("String")) {
field.setAccessible(true);
String fieldValue = (String) field.get(t);
if (StringUtils.isNotEmpty(fieldValue)) {
if (type.equals("Decrypt")) {
fieldValue = PGSQLUtils.decrypt(fieldValue);
} else if (type.equals("Encrypt")) {
fieldValue = PGSQLUtils.encrypt(fieldValue);
}
field.set(t, fieldValue);
}
}
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return t;
}
}
3、编写注解类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptFiled {
String value() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptFiled {
String value() default "";
}
4、需要加解密的实体类注解方式示例
@Data
@EqualsAndHashCode()
@TableName(value="jiami_test",schema = "public")
public class JiamiTest extends BaseEntity implements Serializable{
/**
* 序列
*/
private static final long serialVersionUID = 1L;
/**
*
* openid:openid VARCHAR(128)
*/
@DecryptFiled
@EncryptFiled
private String openid;
/**
*
* channel_id:channel_id VARCHAR(128)
* */
@DecryptFiled
@EncryptFiled
private String channelId;
/**
*
* channel_name:channel_name VARCHAR(128)
*/
@DecryptFiled
@EncryptFiled
private String channelName;
/**
*
* :id INT8(19)
*/
@TableId(value = "id" ,type = IdType.ASSIGN_UUID)
@ApiModelProperty(value = "ID")
private String id;
}
4、调用
/**
* 查询所有加解密测试列表
* @param
* @return
*/
@ApiOperation(value = "查询所有加解密测试列表", notes = "查询所有加解密测试列表")
@PostMapping("searchAll")
public ResponseData<List<JiamiTest>> searchAll() {
List<JiamiTest> jiamiTestList = jiamiTestService.list();
if(!CtgUtils.isCollectionNull(jiamiTestList)) {
JiamiTest jiamiTest = new JiamiTest();
return ResponseData.success(jiamiTest.decryptSelfList(jiamiTestList));
}else {
log.info(JiamiTestConstant.NOT_EXIST);
return ResponseData.success(jiamiTestList);
}
}
/**
* 保存加解密测试
* @param jiamiTest
* @return
*/
@ApiOperation(value = "保存加解密测试", notes = "保存加解密测试")
@PostMapping("save")
public ResponseData<String> save(@RequestBody JiamiTest jiamiTest) {
boolean res = jiamiTestService.save(jiamiTest.encryptSelf());
if(res) {
return ResponseData.success(JiamiTestConstant.SAVE_SUCCESS);
}else {
log.error(JiamiTestConstant.SAVE_FAILED);
return ResponseData.error(JiamiTestConstant.SAVE_FAILED);
}
}
5、效果
数据库中数据
查询出的数据