繁体   English   中英

Java中如何集中数据加解密?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM