這是本文件的舊版!
Jasypt
Problem
使用這個API的目的主要是為了無痛去加解密資料庫的某個欄位,且它支援Hibernate、Spring的整合方式。
How to?
安裝Java Cryptography Extension (JCE)
如果出現Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy File錯誤訊息,請自行到Oracle官網下載JCE包(JCE for Java8),並安裝到%JAVA_HOME%/jre/lib/security中。如果有問題,可以設定JAVA_HOME環境變數再試試看。 (JCE包內容有US_export_policy.jar與local_policy.jar)
Setup Hibernate & Spring
我的Ivy.xml相依於此兩個libraries:
<dependency org="org.jasypt" name="jasypt" rev="1.9.2"/> <dependency org="org.jasypt" name="jasypt-hibernate4" rev="1.9.2"/>
最簡單的方式
只要在hbm檔內,將你要加密的欄位設定一下就搞定了。
Hibernate設定:
<code xml>
<hibernate-mapping>
<typedef name=“encryptedString” class=“org.jasypt.hibernate4.type.EncryptedStringType”>
<param name=“algorithm”>PBEWithMD5AndTripleDES</param>
<param name=“password”>jasypt</param>
<param name=“keyObtentionIterations”>1000</param>
</typedef>
<class name=“org.tonylin.fun.tonyaccounts” table=“tony_accounts”>
<!– Other items –>
<property name=“password” type=“encryptedString”>
<column name=“PASSWORD” not-null=“true” />
</property>
</class>
</hibernate-mapping>
</code>
=== 使用自己的Encryptor ===
Hibernate設定:
<code xml>
<hibernate-mapping>
<typedef name=“encryptedString” class=“org.jasypt.hibernate4.type.EncryptedStringType”>
<param name=“encryptorRegisteredName”>tonyEncryptor</param>
</typedef>
<class name=“org.tonylin.fun.tonyaccounts” table=“tony_accounts”>
<!– Other items –>
<property name=“password” type=“encryptedString”>
<column name=“PASSWORD” not-null=“true” />
</property>
</class>
</hibernate-mapping>
</code>
Spring設定:
<code xml>
<bean id=“strongEncryptor”
class=“org.jasypt.encryption.pbe.StandardPBEStringEncryptor”>
<property name=“algorithm”>
<value>PBEWithMD5AndTripleDES</value>
</property>
<property name=“password”>
<value>jasypt</value>
</property>
<property name=“keyObtentionIterations”>
<value>1000</value>
</property>
</bean>
<bean id=“hibernateStringEncryptor”
class=“org.jasypt.hibernate4.encryptor.HibernatePBEStringEncryptor”>
<property name=“registeredName”>
<value>tonyEncryptor</value>
</property>
<property name=“encryptor”>
<ref bean=“strongEncryptor” />
</property>
</bean>
</code>
==== PowerMock ====
如果有使用PowerMock做測試,記得ignore掉這幾個項目。
<code java>
@PowerMockIgnore({
“javax.crypto.*”,
“javax.security.*”
})
</code>
==== Known Issue ====
目前已知使用Hibernate設定criteria搜尋,又或者是HQL搭配NameParam的方式,都會經過Encryptor。但有以下問題:
- 密文不固定: 使用Jasypt所提供的Password Base相關的加密方式,所產生的密文每次都會不同。如果加密的欄位是要搜尋的對象,變成必須自行處理,也可能因此產生效能問題。如果自行寫Encryptor去產生一樣的密文,就會比較不安全。該怎麼決擇就由你自行決定了。
- 無法模糊比對: 難以使用模糊比對去找加密過後的欄位。因為片段加密後,不一定是密文中的片段。
- 加密型態非預期: 舉例來說,物件類別為long,而DB為big int。而Jasypt提供的類別為EncryptedLongAsStringType,會將內容轉為string。我的測試是MySQL正常,但Postgres會有無法insert的問題;而Jasypt文件就有提到,Long對應的SQL type為VARCHAR, CLOB, TEXT。因此如果要支援,非常可能要自己做Encryptor。
===== Reference =====
* Jasypt與Hibernate的整合
* how-to-install-java-cryptography?
* JCE8
* Jasypt使用HQL上的問題
===== =====
—-