Hibernate ORMとJasyptを組み合わせで、暗号化してデータを保存する方法について紹介された記事はありますが、サンプルとして紹介されているものを見るとマッピング定義ファイル(hbmファイル)にパスワードを直書きする方法がほとんどです。
マッピング定義ファイルにパスワードを直書きせず済ませる方法を紹介します。
(※Hibernate 3.xでの使用例ですので、Hibernate 4.xの際には適宜クラス/メソッドを置き換えてください)
まず、マッピング定義ファイルを下記のように定義します。
typedefでカスタム型「encryptedString」を定義し、encryptorRegisteredNameパラメータでEncryptorの名前を「MyStringEncryptor」とします。
暗号化を行いたいカラムのtypeパラメータを「encryptedString」で定義します。
MyStringEncryptor ...
Java側のソースは下記の通りです。
Encryptorのインスタンスを作成し、パスワードなどのパラメータを設定後、マッピング定義ファイルで定義した名前「MyStringEncryptor」でレジストリにを登録します。
Configuration configuration = (new AnnotationConfiguration()).configure(); StandardPBEStringEncryptor myEncryptor = new StandardPBEStringEncryptor(); myEncryptor.setAlgorithm("PBEWithMD5AndDES"); myEncryptor.setPassword("Jasyptのパスワード"); myEncryptor.setKeyObtentionIterations(1000); HibernatePBEEncryptorRegistry registry = HibernatePBEEncryptorRegistry.getInstance(); registry.registerPBEStringEncryptor("MyStringEncryptor", myEncryptor); SessionFactory sf = configuration.buildSessionFactory(); Session session = sf.openSession();
Encryptorの登録は、実際にエンティティを使用するまでに行えば良いようです。
(org.hibernate.Criteria#list()を行う直前のタイミングで登録を行っても正常に機能しました。)
Jasyptには、org.jasypt.hibernate3パッケージとorg.jasypt.hibernateパッケージがあり、使用しているHibernate周りの環境に合わせて適切なJasyptのパッケージを使用しないと、下記のようにorg.jasypt.exceptions.EncryptionInitializationExceptionが発生してしまうことがあります。
org.jasypt.exceptions.EncryptionInitializationException: No string encryptor registered for hibernate with name "MyStringEncryptor"
ここに気づかずハマりしました… orz
海外のQAサイトでも類似する事例の投稿がありましたが、おそらく原因はこれなのではないかと思います。