2013-05-13 56 views
1

我有一個Employee實體,它使用jasypt加密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); 

我無法理解在我的代碼中是否存在一個錯誤,或者它是如何休眠應該工作。 在文檔Integrating Jasypt with Hibernate 3.x or 4.x,寫的是:

但加密設置你的Hibernate使用中的限制:安全 標準建立在 相同數據的兩個不同的加密操作不應該返回相同的值(由於鹽的隨機使用)。因此,持久保護時設置爲 加密的字段中沒有任何字段可以是您所屬實體的 搜索查詢中的WHERE子句的一部分。

因此,這意味着無法對加密字段執行搜索操作。

回答

1

我正在使用隨機鹽生成器。添加零鹽發生器後,我能夠解決問題:

strongEncryptor.setSaltGenerator(new ZeroSaltGenerator());