文字列をJPAで保存しながら暗号化し、読み取るときに復号化する必要があります。まず、プロパティが汎用であるため、休止状態の構成やその他の構成ファイルを使用することはできません。つまり、プロパティは次のようになります(簡単に言うと、ここですでにいくつかの処理を実装しています)。
@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-およびdecryption自体は機能します。これを確実にするために、異なるJUnitクラスで実行させます。)