2009-07-30 56 views
2

我有一个数据库表,其中包含需要通过Hibernate读取和写入的字段。它是字符串字段,但内容是加密的。由于各种原因(例如需要对纯文本值进行排序),加密/解密功能在数据库内而不是Java中实现。在休眠中自动应用字段转换功能

我现在正在努力的问题是找到一种方法来调用Hibernate生成的SQL中的加密/解密函数,无论该字段是否被引用,并且对我的应用程序代码都是透明的。这可能吗?我研究了Hibernate对“派生”属性的支持,但不幸的是,这种方法不支持读写字段。任何想法赞赏。

+0

你能澄清`排列纯文本位吗?这是否意味着你正在做`SELECT my_field FROM my_table ORDER BY decrypt(my_field)`? – ChssPly76 2009-07-30 16:45:10

+0

是的,但更像SELECT解密(my_field)FROM my_table ORDER BY解密(my_field)。无论如何,这就是一个例子。我还需要执行不区分大小写的搜索(对解密值调用UPPER)以及使用LIKE运算符进行部分字符串匹配。所有这些都要求数据库能够进行解密。 – 2009-07-30 17:43:43

回答

1

事实上,最后我走了一条不同的路线,并向Hibernate提交了patch。它在上周承诺上线,因此我认为它将在3.5之后的下一个版本中发布。现在,在属性映射中,可以指定SQL“读取”和“写入”表达式来调用SQL函数或执行其他类型的数据库端转换。

-1

假设你可以访问加密/从Java内部解密算法,我会成立我的映射类像

public class encryptedTable { 
    @Column(name="encrypted_field") 
    private String encryptedValue; 

    @Transient 
    private String value; 

    public String getEncryptedValue() { 
     return encryptedValue; 
    } 

    public String getValue() { 
     return value; 
    } 

    public void setEncryptedValue(String encryptedValue) { 
     this.encryptedValue = encryptedValue; 
     this.value = decrypt(encryptedValue); 
    } 

    public void setValue(String value) { 
     this.value = value; 
     this.encryptedValue = encrypt(value); 
    } 
} 

然后用获取/设置值作为访问你的程序中,离开获取/设置访问数据库时Hibernates使用的EncryptedValue。

+0

这并没有解决我希望Hibernate在查询中引用该字段(例如用于排序)时自动调用数据库的解密函数的愿望。 – 2009-07-30 15:20:05

1

您可以在数据库中有一个触发器,它在检索时解密该值并替换返回的结果,并在插入时对该值进行加密并将存储的结果替换为加密值。您也可以使用视图封装器来执行此操作 - 即在视图上具有插入触发器,并让视图自动解密该值。

为了更好地解释:有一个解密值的视图,以及一个开启插入触发器来加密链接到视图的值。

+0

我曾经考虑过这样的事情,但由于我有几张带有加密字段的表,并且我依靠Hibernate来自动生成模式,所以我认为它太难维护了。但也许有一种方法可以动态生成视图和触发器。嗯... – 2009-07-30 17:40:30

+0

我们使用类似的方法,但我们有我们的数据库生成,然后我们逆向工程。如果要从对象安装数据库,则可以将视图/触发器的模式作为单独的一部分,然后将其作为安装脚本/执行的一部分安装。 – aperkins 2009-07-30 18:50:45

4

我不认为有一种方法可以像你所描述的那样进行加密,对您的应用程序来说透明的完全是。最接近的事情是让它在实体之外透明。在你的实体类:

@Entity 
@SQLInsert(sql="INSERT INTO my_table(my_column, id) VALUES(encrypt(?),?)") 
@SQLUpdate(sql="UPDATE my_table SET my_column = encrypt(?) WHERE id = ?") 
public class MyEntity { 

    private String myValue; 

    .... 

    @Formula("decrypt(my_column)") 
    public String getValue() { 
    return myValue; 
    } 

    public void setValue(String value) { 
    myValue = value; 
    } 

    @Column (name="my_column") 
    private String getValueCopy() { 
    return myValue; 
    } 

    private void setValueCopy(String value) { 
    } 

} 

value被映射为派生属性,你应该能够在查询中使用它。
valueCopy是私有的,用于绕过只读的派生属性。
SQLInsertSQLUpdate是黑巫术魔法强制加密插入/更新。请注意,参数顺序很重要,您需要找出Hibernate在不使用自定义插入/更新的情况下生成参数的顺序,然后复制它。

-1

为什么不直接使用SQl服务器加密,它似乎已经通过调用Hibernate中的存储过程而不是让Hibernate生成查询?