jpa加密
最近,我不得不将数据库加密添加到一些字段中,并且发现了很多不好的建议。
建筑问题
最大的问题是建筑。 如果持久性管理器静静地处理您的加密,那么根据定义,您的体系结构将在持久性和安全性设计之间要求紧密而不必要的绑定。 您不能触摸一个而不接触另一个。
这似乎是不可避免的,但是有一个受人尊敬的想法,那就是最好的架构是您拥有独立的应用程序开发人员和安全开发人员团队的架构。 应用程序开发人员不能草率,但总的来说,他们唯一的重点是功能完成。 安全开发人员负责设计和实现安全性。 唯一考虑这两个方面的地方是建筑和顶层设计。
过去这不是很实用,但是面向方面的编程(AOP)和类似的概念已经改变了这一点。 现在,在服务层和持久层之间注入一个拦截器是完全合理的,这样,无权允许调用者看到的值被悄悄地丢弃了。 10个项目的列表可能会减少到7个,或者更新可能会引发异常,而不是修改只读值。 当持久化集合时,它要复杂一些,但是一般方法应该很清楚。
这里的关键是,应用程序开发人员无需查看安全代码。 所有这些都可以通过在部署时通过配置文件添加的AOP注入来处理。 更重要的是,它可以随时更改,而无需修改应用程序本身。 (您可能需要执行一个更新过程,该过程将更改数据库中的值。)
拦截器甚至可以阻止对未记录方法的调用-减少了对流氓程序员的担心。
在实践中,许多站点将有几个开发人员都戴上帽子,而不是拥有专门的安全团队。 只要他们能够牢记自己的职责,这不是问题。
在JPA或Hibernate字段中进行透明加密绝对比在POJO中放入加密/解密代码更好,但是它仍然在安全性和持久性层之间强加了不必要的绑定。 它还存在严重的安全问题。
安全问题
每当您要处理加密时,都会遇到一个关键问题–可以将此对象写入磁盘吗? 最明显的威胁是序列化,例如,通过钝化数据以释放内存或将其迁移到其他服务器的应用服务器。
实际上,这意味着您的密钥和纯文本内容必须标记为“ transient”(对于序列化引擎)和“ @Transient”(对于JPA或Hibernate)。 如果您真的很疑惑,您甚至会覆盖隐式序列化方法writeObject,因此可以绝对保证这些字段永远不会写入磁盘。
这是可行的……但是它使透明的加密/解密大为失败,因为该代码的全部目的是使这些字段看起来就像另一个字段。 您必须维护两个字段-持久加密值和瞬态未加密值-并具有某种使它们保持同步的方法。 无需在您的pojo中放入任何密码即可完成所有操作。
一个更微妙的问题是,如果攻击者可以通过使应用服务器崩溃而触发核心转储,则您的对象仍可能写入磁盘。 细心的站点管理员将禁用核心转储,但许多人忽略了它。 解决这个问题比较困难,但是如果AOP可以在需要解密值的方法周围立即解密/加密值,则有可能。 您的应用程序不关心解密在哪里发生,只要它在需要时进行解密即可。 这是应该留给安全团队的决策类型。
可以将对象写入磁盘的第三种方法是通过OS交换文件,但这应该不是问题,因为交换文件现在通常已加密。
JPA实体侦听器
一个解决方案是JPA <