简体   繁体   English

Spring JPA @Converter-如何使用实体自己的id作为盐来加密实体?

[英]Spring JPA @Converter - How to encrypt entity using it's own id as salt?

So I have this case where the JPA entity is encrypted using it's own ID as salt. 因此,在这种情况下,JPA实体使用其自己的ID作为Salt进行了加密。

Here is an example of doing the en/decrypt without annotation, I have to "manually" create custom get/setter to each encrypted fields. 这是不带注释执行en / decrypt的示例,我必须“手动”为每个加密字段创建自定义get / setter。

StandardDbCipher is just my cipher class that accepts a salt during construction (which is in this case is the ID field). StandardDbCipher只是我的密码类,在构造期间接受盐(在本例中为ID字段)。 The password is already fixed in some other file. 密码已在其他文件中固定。

@Entity
public class Applicant implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;

    private String profilePic;

    private String contact;

    private String personalInfo;

    @Transient
    private StandardDbCipher cipher;

    private StandardDbCipher getCipher() {
        if (cipher == null) {
            cipher = new StandardDbCipher(id);
        }
        return cipher;
    }

    private String encrypt (String plain) {
        return getCipher().decrypt(plain);
    }

    private String decrypt (String crypt) {
        return getCipher().encrypt(crypt);
    }

    public String getProfilePic() {
        return decrypt(profilePic);
    }

    public void setProfilePic(String profilePic) {
        this.profilePic = encrypt(profilePic);
    }

    public String getContact() {
        return decrypt(contact);
    }

    public void setContact(String contact) {
        this.contact = encrypt(contact);
    }

    public String getPersonalInfo() {
        return decrypt(personalInfo);
    }

    public void setPersonalInfo(String personalInfo) {
        this.personalInfo = encrypt(personalInfo);
    }

}

I would like to simplify the code and reduce boilerplate using @Converter , but couldn't figure out how to put the ID as salt? 我想使用@Converter简化代码并减少样板,但无法弄清楚如何将ID设置为salt? Any ideas? 有任何想法吗? Maybe other annotation? 也许其他注释?

If it's something that you need to do in many entities, then I think you can try Aspect Oriented Programming (the most known implementation is AspectJ). 如果您需要在许多实体中执行此操作,那么我认为您可以尝试面向方面的编程(最著名的实现是AspectJ)。 Spring also has an integration with that (I've not worked with that as I'm not using Spring). Spring也对此进行了集成(因为我没有使用Spring,所以我没有使用它)。 The idea is that you can have some intercepting code that would be executed before or after a call to methods of your objects (in your case getter/setter methods of your entities) and inside them you can manipulate the actual object/parameters/return values. 这个想法是,您可以在调用对象的方法(在您的情况下为实体的getter / setter方法)之前或之后执行一些拦截代码,并且在其中可以操纵实际的对象/参数/返回值。

You can call your encrypt method before the execution of setter method and pass the encrypted value to your setter. 您可以在执行setter方法之前调用crypto方法,并将加密后的值传递给setter。 For the decryption, you run your decrypt method after the execution of the getter method. 对于解密,可以在执行getter方法之后运行您的解密方法。

By doing so, your entities would remain as a simple POJO and you don't need to provide a converter for each. 这样,您的实体将保持为简单的POJO,并且您无需为每个实体提供转换器。

. Here are some tutorial demonstrating the AOP concept: 以下是一些演示AOP概念的教程:

Update: Another solution could be to use JPA Entity Listeners . 更新:另一个解决方案可能是使用JPA实体侦听器 You can do the encryption on @PrePersist and the decryption on @PostLoad callbacks in your entity or use a single listener class for all such entities. 您可以在实体中对@PrePersist进行加密,对@PostLoad回调进行解密,或者对所有此类实体使用单个侦听器类。 You would just need to annotate your POJOs like this: 您只需要这样注释您的POJO:

@Entity
@EntityListeners(class=EncDecListener.class)
public class Applicant implements Serializable {

}

public class EncDecListener {
    @PreUpdate
    public void encrypt(Applicatnt a) {
        // do encryption
    }


    @PostLoad
    public void decrypt(Applicatnt a) {
        // do decryption
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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