1

我有一个使用 jasypt 加密 ssn 字段的 Employee 实体。以下是一个模拟定义:

@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);

我无法理解我的代码中是否存在错误,或者休眠应该如何工作。在Integrating Jasypt with Hibernate 3.x or 4.x文档中,写道:

但是加密对您的 Hibernate 使用设置了限制:安全标准规定,对相同数据的两种不同加密操作不应返回相同的值(由于使用了随机盐)。因此,在持久化时设置为加密的任何字段都不能成为它们所属实体的搜索查询中的 WHERE 子句的一部分。

因此,这意味着无法对加密字段执行搜索操作。

4

1 回答 1

1

我使用的是随机盐发生器。添加零盐发生器后,我能够解决问题:

strongEncryptor.setSaltGenerator(new ZeroSaltGenerator());
于 2013-05-14T05:45:29.210 回答