[英]How to centralize data encryption and decryption in Java?
我有两个函数来加密和解密数据。
我当前的代码如下。 我有实体 class、DTO class、存储库和服务 class。 名称在保存到数据库之前需要加密,在从数据库中检索时需要解密。
假设我有 10 个不同的实体类需要做加密和解密数据,我需要将加密和解密 function 添加到每个服务 class 如下代码。
有没有办法在一项服务 class 中为所有实体完成所有加密和解密数据? 喜欢在实体中覆盖 Get 和 Set 方法? 任何人都可以建议吗? 非常感谢。
@Entity
@Getter
@Setter
public class Customer {
private Long id;
private String name;
private String contact;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CustomerDTO {
private String name;
}
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>{
}
@Service
public class CustomerService {
@Autowired
private CustomerRepository customerRepository;
@Autowired
private EncrytionService encrytionService;
public void save(String name){
Customer customer = new Customer();
customer.setName(encrytionService.doEncrypt(name));
customerRepository.save(customer);
}
public CustomerDTO getCustomer(Long customerId) {
Customer customer = customerRepository.findById(customerId);
CustomerDTO dto = new CustomerDTO();
dto.setName(encrytionService.doDecrypt(customer.getName()));
return dto;
}
}
不确定有没有办法轻松做到这一点(有点开箱即用的方式),但也许你可以尝试使用 JPA 生命周期事件和EntityListener
自己实现一些东西。
例如:
// this is going to be our EntityListener
public class SensitiveDataListener {
@PrePersist
void beforeAnyPersist(Customer customer) {
// encrypt what you need and set
// e.g. customer.setName(encrytionService.doEncrypt(customer.getName()));
}
// after an entity has been loaded
@PostLoad
void afterLoad(Customer customer) {
// decrypt what you need
}
}
// and this is how you add it to your entity
@EntityListeners(SensitiveDataListener.class)
@Entity
public class Customer {
//...
}
这里的一个好问题是 - 好的,我有多个实体,我该怎么办 - 创建多个**Listener
类? 一般来说,没有。 您的侦听器可以“处理”多个实体,但如何实现它 - 取决于您需要什么 - 例如,如果您需要加密/解密不同实体中的不同字段,这是一种情况,如果您需要加密/解密让我们说name
并且您在不同的实体中有此字段,这将是另一种情况和另一种解决方案。 此外,您可能希望再次加密所有内容,这将是一个不同的解决方案,因为它是另一个用例。
如果它是同一个字段,您可能可以“统一”您的实体(但请记住,有时当您的实体实现某些接口时这不是一个好主意):
public interface Sensitive {
void setName(final Date date);
}
@EntityListeners(SensitiveDataListener.class)
@Entity
public class Entity1 implements Sensitive {
// override setName
}
@EntityListeners(SensitiveDataListener.class)
@Entity
public class Entity2 implements Sensitive {
// override setName
}
// but then your SensitiveDataListener will look like this
public class SensitiveDataListener {
@PrePersist
void beforeAnyPersist(Sensitive entity) {
// encrypt what you need and set
// e.g. entity.setName(encrytionService.doEncrypt(entity.getName()));
}
// after an entity has been loaded
@PostLoad
void afterLoad(Sensitive entity) {
// decrypt what you need
}
}
也许你也可以使用AttributeConverter ,假设你的字段是String
并且编码的值也是String
你可以创建转换器来编码/解码你的东西,但是你需要将它添加到你想要编码的每个字段(在每个实体中)。
像这样的东西:
@Convert(converter = MyAttributeConverter.class)
private String name; // this is entity field
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.