我们需要在使用JPA存储它们时对其进行加密,并在读取时对其进行解密。首先,我们不能使用一些hibernate配置或任何其他配置文件,因为我们的属性是通用的。这意味着我们的属性看起来像这样(简单来说,我们已经在这里实现了一些处理):
@Entity
@Table(name = "PROPERTY")
@Access(AccessType.FIELD)
public class Property implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "PRO_ID")
private long id;
@Version
@Temporal(value = TemporalType.TIMESTAMP)
@Column(name = "PRO_VERSION")
private Date version;
@Column(name = "PRO_KEY")
private String key;
@Transient
private String value;
@Column(name = "PRO_ENCRYPTED")
private boolean encrypted = false;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public Date getVersion()
{
return version;
}
public void setVersion(Date version)
{
this.version = version;
}
public String getKey()
{
return key;
}
public void setKey(String key)
{
this.key = key;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
public boolean isEncrypted()
{
return encrypted;
}
public void setEncrypted(boolean encrypted)
{
this.encrypted = encrypted;
}
@Access(AccessType.PROPERTY)
@Column(name = "PRO_VALUE")
protected String getValueDatabase()
{
// TODO: add decryption
return value;
}
protected void setValueDatabase(String value)
{
// TODO: add encryption
this.value = value;
}
}
(我们可以通过isEncrypted()方法区分要加密的属性。根据属性设置为true或false)。 Out Encryptor类(简化)适用于Jasypt:
public final class MyEncrypter
{
private static final String password = "AHKG@a4SjHH5%j%974";
private static final StandardPBEStringEncryptor encryptor;
static
{
encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(password);
}
public final static String encrypt(String string)
{
return encryptor.encrypt(string);
}
public final static String decrypt(String encrypted)
{
return encryptor.decrypt(encrypted);
}
}
加密/解密有效。实际上我们的整个持久性处理工作。我们可以保存加密数据。但是,当我们读取加密数据时,我们得到以下结果:
javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [at.jit.remind.jee.domain.context.model.Property#10]
奇怪的是,只有当Hibernates尝试更新加密文本时才会发生这种情况。但是当我们对我们的文本进行伪加密和伪解密时,它不会发生。这意味着我们反转文本,用Hibernate存储反向文本,并在Hibernate尝试更新它时“解密”它。所以我们的整个处理工作,但是当我们使用“真正的”加密时它可能不起作用的原因是什么?有什么想法吗?
(同样,en-和解密本身也可以。我让它在不同的JUnit类中运行以确保这一点。)
答案 0 :(得分:1)
我们决定使用另一种加密方式,因为显然jasypt对Hibernate做了一些奇怪的事情。似乎这种加密/解密在某种程度上会产生Hibernate的“脏标志”,因此Hibernate会尝试更新数据库条目,尽管加密会同时更改值。无法隔离它。
答案 1 :(得分:0)
这是因为您的对象仍然附加到hibernate会话并且其内部状态已更改。首先尝试调用session.evict(object),然后更改要加密的文本。