jasypt ZeroSaltGenerator generates different encrypted strings in Spring + Hibernate

In our Spring + hibernate based web application I configured jasypt for encrypting user contact numbers stored in the DB. It worked fine for the encryption as the database contains encrypted strings and also the values were decrytped and displayed correctly on the UI. The problem is that we also need to use the encrypted column in the WHERE clause of a search query. As suggested in many threads on SO and other forums the solution was to use a ZeroSaltGenerator so that the salt is not random and the encrypted string is always same for a particular string. My bean configuration looks like this:

<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>

The entity class contains the following typedef:

@TypeDef (name="encryptedString", typeClass= EncryptedStringType.class,
parameters = {
        @Parameter(name="encryptorRegisteredName", value="hibernateStringEncryptor")
    }
)

and the column is annotated as so

@Column(name = "user_mobileno")
@Type(type="encryptedString")
private String userMobileNumber;

The result is however different encrypted strings for the same contact number. Interestingly, a stand alone java program with the same configuration outputs correct results as expected

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=

Any hints on where this could have gone wrong in the webapp please?

Edit #1 Upon invetigating further by debugging in eclipse with attached sources, the generateSalt() method of RandomSaltGenerator is invoked everytime eventhough a ZeroSaltGenerator is configured in the xml. Could not get why it should be invoked instead of the method in ZeroSaltGenerator.

Answers


After a lot of debugging, I found that the salt generator was always RandomSaltGenerator regardless of the bean configuration in xml.

There was also another Entity that was having the same typedef with EncryptedStringType.class. However it contained @Parameter annotations directly specifying the password, algorithm etc., So it did not refer to the hibernateStringEncryptor that was used by the first Entity.

As a result, it was initiating a fresh StandardPBEStringEncryptor (which uses a RandomSaltGenerator by default) which was also referred by the already instantiated hibernateStringEncryptor.

Once I updated the second Entity to have the same typedef as in the first, it worked as expected.

Happy to help ;)


Need Your Help

Spliting a 16 bits value to 12+4 python struct

python struct bits

This question is related to this post :

Unable to Add NTP servers in ESX Server

esxi

While adding the ntp server received the following error: