在我们基于Spring + hibernate的Web应用程序中,我配置了jasypt来加密存储在DB中的用户联系号码。它适用于加密,因为数据库包含加密字符串,并且值也在UI上正确解密和显示。问题是我们还需要在搜索查询的WHERE
子句中使用加密列。正如在SO和其他论坛上的许多主题中所建议的那样,解决方案是使用ZeroSaltGenerator,以便salt不是随机的,并且加密字符串对于特定字符串始终是相同的。我的bean配置如下所示:
<bean id="hibernateStringEncryptor" class="org.jasypt.hibernate4.encryptor.HibernatePBEStringEncryptor">
<property name="registeredName" value="hibernateStringEncryptor" />
<property name="encryptor">
<ref bean="strongEncryptor" />
</property>
</bean>
<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="saltGenerator">
<bean class="org.jasypt.salt.ZeroSaltGenerator" />
</property>
</bean>
实体类包含以下typedef:
@TypeDef (name="encryptedString", typeClass= EncryptedStringType.class,
parameters = {
@Parameter(name="encryptorRegisteredName", value="hibernateStringEncryptor")
}
)
并且该列标注为
@Column(name = "user_mobileno")
@Type(type="encryptedString")
private String userMobileNumber;
但是,对于相同的联系号码,结果是不同的加密字符串。有趣的是,具有相同配置的独立java程序可以按预期输出正确的结果
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");
encryptor.setPassword("jasypt");
SaltGenerator saltGenerator = new ZeroSaltGenerator();
encryptor.setSaltGenerator(saltGenerator);
System.out.println(encryptor.encrypt("hello"));
System.out.println(encryptor.encrypt("hello"));
O / P:
AvuVEQWIReI=
AvuVEQWIReI=
有关webapp可能出错的任何提示吗?
编辑#1 通过使用附加源在eclipse中进行调试进一步调查,每次在xml中配置ZeroSaltGenerator时都会调用RandomSaltGenerator的generateSalt()方法。无法理解为什么应该调用它来代替ZeroSaltGenerator中的方法。
答案 0 :(得分:0)
经过大量调试后,我发现无论xml中的bean配置如何,salt生成器始终是RandomSaltGenerator。
还有另一个Entity
与EncryptedStringType.class
具有相同的typedef。但是它包含直接指定密码,算法等的@Parameter
注释,因此它没有引用第一个hibernateStringEncryptor
使用的Entity
。
因此,它启动了一个新的StandardPBEStringEncryptor
(默认情况下使用RandomSaltGenerator
),这也是已经实例化的hibernateStringEncryptor
引用的。
我将第二个Entity
更新为具有与第一个相同的typedef后,它按预期工作。
乐意提供帮助;)