Не удалось получить объект с помощью именованного запроса в зашифрованном столбце jasypt

У меня есть объект Employee с полем ssn, зашифрованным с помощью jasypt. Ниже приводится фиктивное определение:

@TypeDef(name = "encryptedString", typeClass = EncryptedStringType.class, parameters = {@Parameter(name = "encryptorRegisteredName",value = "strongHibernateStringEncryptor")})
@Entity
@Table(name="employee")
@NamedQueries(value = {
    @NamedQuery(name = "employee.getEmployeeBySSN", query = "SELECT employee from Employee employee WHERE employee.ssn=:ssn"),
    @NamedQuery(name = "employee.getEmployeeByName", query = "SELECT employee from Employee employee WHERE employee.name=:name")
    })
public class Employee {

    @Id @GeneratedValue
    private Long id;

    private String name;

    @Type(type = "encryptedString")
    private String ssn;
}

Этот объект содержит два именованных запроса для получения сотрудников, один с именем, а другой с ssn. Поле SSN зашифровано с помощью jasypt. Код представляет собой фиктивную реализацию, поэтому я использовал следующую базовую конфигурацию:

public static void main(String[] args) throws SerialException, SQLException {

    //Configure jasypt encryptor
    PooledPBEStringEncryptor strongEncryptor = new PooledPBEStringEncryptor();
    strongEncryptor.setAlgorithm("PBEWITHMD5ANDDES");
    strongEncryptor.setPassword("jasypt");
    strongEncryptor.setPoolSize(2);

    //Register it with hibernate
    HibernatePBEEncryptorRegistry registry = HibernatePBEEncryptorRegistry.getInstance();
    registry.registerPBEStringEncryptor("strongHibernateStringEncryptor", strongEncryptor);

    //Get an entity manager factory
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");

    //Get an entity manager
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    tx.begin();

    //Create an employee
    Employee employee = new Employee();
    employee.setName("Vaibhav");
    employee.setSsn("1234567");
    em.persist(employee);

    tx.commit();

    EntityTransaction newtx = em.getTransaction();
    newtx.begin();

    //Search an employee with ssn
    Query queryObject1 = em.createNamedQuery("employee.getEmployeeBySSN");
    queryObject1.setParameter("ssn", "1234567");

    //No results here
    List employees1 = queryObject1.getResultList();

    newtx.commit();
    em.close();

}

Я не получаю результата в списке employees1. Однако, когда я запускаю следующий именованный запрос, я могу увидеть расшифрованный ssn в объекте сотрудника.

Query queryObject = em.createNamedQuery("employee.getEmployeeByName");
queryObject.setParameter("name", "Vaibhav");
List employees = queryObject.getResultList();
Employee employee1 = (Employee)employees.get(0);

Я не могу понять, есть ли ошибка в моем коде или это то, как должен работать спящий режим. В документации Интеграция Jasypt с Hibernate 3.x или 4.x написано, что:

Но шифрование накладывает ограничение на использование Hibernate: стандарты безопасности устанавливают, что две разные операции шифрования одних и тех же данных не должны возвращать одно и то же значение (из-за использования случайной соли). Из-за этого ни одно из полей, для которых установлено шифрование при сохранении, не может быть частью предложения WHERE в ваших поисковых запросах для сущности, которой они принадлежат.

Таким образом, это означает, что нельзя выполнять операции поиска в зашифрованном поле.


person Vaibhav    schedule 13.05.2013    source источник


Ответы (1)


Я использовал генератор случайных солей. После добавления генератора нулевой соли я смог решить проблему:

strongEncryptor.setSaltGenerator(new ZeroSaltGenerator());
person Vaibhav    schedule 14.05.2013