Hibernate加密数据库对应用程序完全透明 [英] Hibernate Encryption of Database Completely Transparent to Application

查看:175
本文介绍了Hibernate加密数据库对应用程序完全透明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Grails 1.0.4项目,该项目必须在不到两周的时间内发布,客户只需要对数据库中的所有数据进行加密。

I'm working on a Grails 1.0.4 project that has to be released in less than 2 weeks, and the customer just came up with a requirement that all data in the database should be encrypted.

由于应用程序本身的每个数据库访问的加密可能需要很多时间,并且容易出错,所以我寻求的解决方案是对应用程序透明的加密。

Since encryption of every database access in the application itself could take a lot of time and will be error prone, the solution I seek is some kind of encryption transparent to the application.

有没有办法设置Hibernate加密所有表中的所有数据(除了可能的id和版本列)或者我应该寻求一个MySQL解决方案(我们使用MySQL 5.0)?

Is there a way to setup Hibernate to encrypt all data in all tables (except maybie the id and version columns) or should I seek a MySQL solution (we're using MySQL 5.0) ?

编辑:
感谢所有的替代解决方案的帖子,如果客户改变主意,这将是巨大的。现在,要求是数据库中没有纯文本。

Thanks for all of your posts for alternative solutions, if the customer changes mind it would be great. As for now, the requirement is "No plain text in the Database".

我要指出的第二件事是,我使用Grails,不熟悉它,这是一个配置的约定,所以即使对应用程序的非常规的更改应该避免。

Second thing I'd like to point out is that I'm using Grails, for those not fammiliar with it, It's a convention over configuration, so even small changes to the application that are not by convention should be avoided.

推荐答案

很久以来,我已经问了这个问题。在此期间,感谢所有的答案。在处理加密整个数据库的原始想法时,它们是巨大的,但是要求改为只加密敏感的用户信息,如名称和地址。所以解决方案就像下面的代码。

Well it has been a long time since I've asked the question. In the meantime, thanks for all the answers. They were great when dealing with the original idea of encrypting the entire database, but the requirement changed to only encrypting sensitive user info, like name and address. So the solution was something like the code down below.

我们实现了一个Encrypter从记录中读取加密方法(因此每个记录可以有不同的加密)并使用它将临时重复字段连接到在数据库中加密的字段。增加的优点/缺点是:

We've implemented an Encrypter which reads the encryption method from the record ( so there can be different encryption per record) and use it to connect transient duplicate fields to the ones encrypted in the database. The added bonus/drawbacks are:


  • 数据也在内存中加密,所以每次访问方法getFirstName都会解密数据有一种方法来缓存解密的数据,但我不需要它在这种情况下)

  • 加密字段不能与默认grails / hibernate方法用于搜索数据库,在服务中获取数据的自定义方法,加密它,然后在查询的where子句中使用加密的数据。使用User.withCriteria时很容易

  • The data is also encrypted in memory, so every access to the method getFirstName descrypts the data (I guess there is a way to cache decrypted data, but I dont need it in this case)
  • Encrypted fields cannot be used with default grails/hibernate methods for search through database, we've made custom methods in services that get data, encrypt it and then use the encrypted data in the where clause of a query. It's easy when using User.withCriteria

class User {

class User {

byte[] encryptedFirstName
byte[] encryptedLastName
byte[] encryptedAddress

Date dateCreated // automatically set date/time when created
Date lastUpdated // automatically set date/time when last updated

EncryptionMethod encryptionMethod = ConfigurationHolder.config.encryption.method

def encrypter = Util.encrypter

static transients = [ 
'firstName', 
'lastName', 
'address',
'encrypter'
]

static final Integer BLOB_SIZE = 1024

static constraints = {

    encryptedFirstName maxSize: BLOB_SIZE, nullable: false
    encryptedLastName maxSize: BLOB_SIZE, nullable: false

    encryptedAddress maxSize: BLOB_SIZE, nullable: true

    encryptionMethod nullable: false

} // constraints

String getFirstName(){
    decrypt('encryptedFirstName')
}

void setFirstName(String item){     
    encrypt('encryptedFirstName',item)
}

String getLastName(){
    decrypt('encryptedLastName')
}

void setLastName(String item){
    encrypt('encryptedLastName',item)       
}

String getAddress(){
    decrypt('encryptedAddress')
}

void setAddress(String item){
    encrypt('encryptedAddress',item)        
}

byte[] encrypt(String name, String value) {

    if( null == value ) {
        log.debug "null string to encrypt for '$name', returning null"
        this.@"$name" = null
        return
    }

    def bytes = value.getBytes(encrypter.ENCODING_CHARSET)
    def method = getEncryptionMethod()


    byte[] res 

    try {
        res = encrypter.encrypt( bytes, method )            
    } catch(e) {
        log.warn "Problem encrypting '$name' data: '$string'", e
    }

    log.trace "Encrypting '$name' with '$method' -> '${res?.size()}' bytes"

    this.@"$name" = res

}

String decrypt(String name) {

    if(null == this.@"$name") {
        log.debug "null bytes to decrypt for '$name', returning null"
        return null
    }

    def res 
    def method = getEncryptionMethod()

    try {
        res = new String(encrypter.decrypt(this.@"$name", method), encrypter.ENCODING_CHARSET )
    } catch(e) {
        log.error "Problem decrypting '$name'", e
    }

    log.trace "Decrypting '$name' with '$method' -> '${res?.size()}' bytes"

    return res
}

}

这篇关于Hibernate加密数据库对应用程序完全透明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆