我正在一个Grails 1.0.4项目中工作,该项目必须在不到2周的时间内发布,并且客户刚提出一个要求,即应该加密数据库中的所有数据。
由于对应用程序本身中的每个数据库访问进行加密可能会花费大量时间,并且容易出错,因此我寻求的解决方案是对应用程序透明的某种加密。
有没有一种方法可以将Hibernate设置为加密所有表中的所有数据(可能不包括id和version列),还是应该寻求MySQL解决方案(我们使用的是MySQL 5.0)?
编辑:感谢您为替代解决方案提供的所有帖子,如果客户改变主意,那将是很好的。到目前为止,要求是“数据库中没有纯文本”。
我想指出的第二件事是,我正在使用Grails,对于那些不熟悉它的人,这是对配置的约定,因此即使对应用程序进行的较小更改也应避免约定。
自从我问了这个问题以来已经有很长时间了。同时,感谢您的所有回答。当处理最初加密整个数据库的想法时,它们很棒,但是要求变为只加密敏感的用户信息,例如名称和地址。因此解决方案类似于下面的代码。
我们已经实现了一个加密器,该加密器从记录中读取加密方法(因此每个记录可以有不同的加密),并使用它来将瞬态重复字段与数据库中加密的字段连接起来。增加的红利/缺点是:
类用户{
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 }
}