2009-07-30 15 views
2

私はHibernateから読み書きする必要のあるフィールドを持つデータベーステーブルを持っています。文字列フィールドですが、内容は暗号化されています。そして、様々な理由(例えば、プレーンテキスト値をソートする必要性)のために、暗号化/復号化機能はJavaではなくデータベース内で実装される。Hibernateでフィールド変換関数を自動的に適用する

私が今苦労している問題は、Hibernateで生成されたSQLのどこでもフィールドが参照され、アプリケーションコードに透過的な方法で暗号化/復号化関数を呼び出す方法を見つけることです。これは可能ですか?私はHibernateの "派生"プロパティのサポートを検討しましたが、残念ながら、そのアプローチは読み書きフィールドをサポートしていません。任意のアイデアを高く評価

+0

'平文テキストをソートする 'ビットを明確にすることはできますか?つまり、SELECT my_field FROM my_table ORDER BY decrypt(my_field) 'のようなことをしているのでしょうか? – ChssPly76

+0

はい、ただし、SELECT decrypt(my_field)FROM my_table ORDER BY decrypt(my_field)のようになります。とにかくその一例です。また、大文字と小文字を区別しない検索(復号化された値でUPPERを呼び出す)と、LIKE演算子を使用して文字列の部分一致を行う必要があります。これらすべてのことは、データベースが解読を行うことができる必要があります。 –

答えて

1

実際には、私は別のルートを行って、patchをHibernateに提出しました。先週はトランクに就きましたので、3.5に続く次のリリースになると思います。プロパティのマッピングでは、SQL関数を呼び出すためのSQL "read"および "write"式を指定したり、他の種類のデータベース側変換を実行することができます。

-1

私は

public class encryptedTable { 
    @Column(name="encrypted_field") 
    private String encryptedValue; 

    @Transient 
    private String value; 

    public String getEncryptedValue() { 
     return encryptedValue; 
    } 

    public String getValue() { 
     return value; 
    } 

    public void setEncryptedValue(String encryptedValue) { 
     this.encryptedValue = encryptedValue; 
     this.value = decrypt(encryptedValue); 
    } 

    public void setValue(String value) { 
     this.value = value; 
     this.encryptedValue = encrypt(value); 
    } 
} 

のように私のマッピングされたクラスに何かを設定し、その後、プログラム内のアクセサとして取得/設定した値を使用して残して、Javaの中からアルゴリズムを復号化/あなたが暗号化へのアクセス権を持っているだろうと仮定すると、データベースへのアクセス時に、HibernateのEncryptedValueを取得/設定します。

+0

これは、照会でフィールドが参照されている(例えば、ソートのために)ときに、Hibernateに自動的にデータベースの解読関数を呼び出させたいという私の望みには対応していません。 –

1

データベースの内部にトリガを置くと、取得時に値を復号化し、返された結果を置き換え、挿入時に値を暗号化して保存された結果を暗号化された値に置き換えます。また、ビューラッパーでこれを行うこともできます。つまり、ビューに挿入トリガーを設定し、そのビューが自動的に値を復号化するようにすることができます。

さらに説明すると、値を復号化するビューがあり、ビューにリンクされている値を暗号化する挿入トリガーがあります。

+0

私はこのようなことを考えましたが、暗号化されたフィールドを持つ複数のテーブルがあり、自動スキーマ生成のためにHibernateに依存しているため、維持管理が難しいと判断しました。しかし、ビューやトリガを動的に生成する方法があります。うーん... –

+0

これにも同様のアプローチを使用しますが、データベースを生成してリバースエンジニアリングします。オブジェクトからデータベースをインストールする場合は、ビュー/トリガーのスキーマを別個のピース​​として使用し、後でインストールスクリプト/実行の一部としてインストールすることもできます。 – aperkins

+0

データベース・トリガーは、データが挿入または更新されたとき、または選択されていないときに呼び出されます。 – HLGEM

4

説明したように暗号化する方法はありません完全にはアプリケーションに透過的です。あなたが得ることができる最も近いものは、エンティティの外側でそれを透明にすることです。あなたのエンティティクラスで:

@Entity 
@SQLInsert(sql="INSERT INTO my_table(my_column, id) VALUES(encrypt(?),?)") 
@SQLUpdate(sql="UPDATE my_table SET my_column = encrypt(?) WHERE id = ?") 
public class MyEntity { 

    private String myValue; 

    .... 

    @Formula("decrypt(my_column)") 
    public String getValue() { 
    return myValue; 
    } 

    public void setValue(String value) { 
    myValue = value; 
    } 

    @Column (name="my_column") 
    private String getValueCopy() { 
    return myValue; 
    } 

    private void setValueCopy(String value) { 
    } 

} 

valueが派生プロパティとしてマッピングされている、あなたは、クエリでそれを使用することができるはずです。
valueCopyはプライベートであり、派生プロパティを読み取り専用にするために使用されます。
およびSQLUpdateは、挿入/更新時に強制的に暗号化するためのブラック・ブードゥー・マジックです。パラメータの順序であることに注意してください。カスタム挿入/更新を使わずにHibernateがどのような順序でパラメータを生成し、それを複製するかを知る必要があります。

+0

このような概念の証明をしました。私は "偽の"プロパティに夢中ではありませんが、私はビューと組み合わせて明示的なINSERTとUPDATEを使用する考えが好きです。ありがとう。 –

-1

Hibernateでクエリを生成させるのではなく、Hibernateでストアドプロシージャを呼び出してSQlサーバ暗号化を使用するだけではどうですか?

+0

ストアドプロシージャは、クエリで参照されたときにフィールドを自動的に復号化する問題に対処しません。 –

関連する問題