如何使用JPA Type Converter加密数据

几天前,我读了Bear Giles关于2012年使用JPA监听器进行数据库加密的有趣文章。他讨论了对加密解决方案的要求,并提供了JPA监听器的代码示例。 他的主要要求是:

  • 提供不影响应用程序的透明加密,
  • 能够在部署时添加加密,
  • 由两个不同的团队/人员开发应用程序和安全性/加密。

我完全同意他的看法。 但是,经过1.5年的时间和对JPA 2.1的规范更新,JPA侦听器不再是唯一的解决方案。 JPA 2.1引入了类型转换器,可用于创建可能更好的解决方案。

一般信息和设置

该示例期望您具有有关JPA类型转换器的一些基本知识。 如果您想更详细地了解类型转换器,请查看我以前关于JPA 2.1 –如何实现类型转换器的文章 。

以下示例的设置很小。 您只需要与Java EE 7兼容的应用程序服务器。 我用Wildfly 8.0.0.Final包含休眠4.3.2.Final作为JPA实现。

创建CryptoConverter

付款信息(如信用卡号)是应加密的机密信息。 以下代码片段显示了我们将在此示例中使用的CreditCard实体。

@Entity
public class CreditCard {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String ccNumber;private String name;...
}

正如我们一开始所指出的,加密应该以透明的方式进行。 这意味着该应用程序不受加密影响,并且可以在不更改现有代码库的情况下对其进行添加。 对我来说,这还包括数据库中的数据模型,因为它通常是由某些应更改的应用程序特定脚本创建的。 因此,我们需要一个类型转换器,在加密和解密信息时不更改数据类型。

下面的代码片段显示了这种转换器的示例。 如您所见,转换器非常简单。 在将实体持久存储到数据库之前,hibernate会调用convertToDatabaseColumn方法。 它从实体获取未加密的字符串,并使用带有PKCS5Padding的AES算法进行加密。 然后,使用base64编码将加密的byte []转换为字符串 ,该字符串将保留在数据库中。

当持久性提供程序从数据库读取实体时,将调用convertToEntityAttribute方法。 它从数据库中获取加密的String ,使用base64解码将其转换为byte []并执行解密。 解密后的字符串将分配给实体的属性。

对于真实的应用程序,您可能需要花费更多的精力进行加密或将其移至单独的类。 但这足以说明一般想法。

@Converter
public class CryptoConverter implements AttributeConverter<String, String> {private static final String ALGORITHM = "AES/ECB/PKCS5Padding";private static final byte[] KEY = "MySuperSecretKey".getBytes();@Overridepublic String convertToDatabaseColumn(String ccNumber) {// do some encryptionKey key = new SecretKeySpec(KEY, "AES");try {Cipher c = Cipher.getInstance(ALGORITHM);c.init(Cipher.ENCRYPT_MODE, key);return Base64.encodeBytes(c.doFinal(ccNumber.getBytes()));} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic String convertToEntityAttribute(String dbData) {// do some decryptionKey key = new SecretKeySpec(KEY, "AES");try {Cipher c = Cipher.getInstance(ALGORITHM);c.init(Cipher.DECRYPT_MODE, key);return new String(c.doFinal(Base64.decode(dbData)));} catch (Exception e) {throw new RuntimeException(e);}}
}

好的,我们有一个类型转换器,可以对字符串进行加密和解密。 现在,我们需要告诉休眠模式使用该转换器来保留CreditCard实体的ccNumber属性。 如前一篇文章中所述 ,我们可以使用@Convert注释。 但这将更改我们应用程序的代码。

另一个也是我们的要求,更好的选择是在XML配置中分配转换器。 这可以在orm.xml文件中完成。 以下代码段将CryptoConverter分配给CreditCard实体的ccNumber属性。

<entity-mappings version="2.1"xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"><entity class="blog.thoughts.on.java.jpa21.enc.entity.CreditCard"><convert converter="blog.thoughts.on.java.jpa21.enc.converter.CryptoConverter" attribute-name="ccNumber"/></entity>
</entity-mappings>

这就是我们为单个数据库字段实现和配置基于类型转换器的加密所需要做的一切。

实体侦听器还是类型转换器?

这个问题的答案并不像看起来那样容易。 两种解决方案都有其优点和缺点。

Bear Giles描述的实体侦听器可以在加密过程中使用实体的多个属性。 因此,您可以加入多个属性,对其进行加密,然后将加密的数据存储在一个数据库字段中。 或者,您可以对加密和解密的数据使用不同的属性,以避免对解密的数据进行序列化( 如Bear Giles所述 )。 但是使用实体侦听器也有缺点。 它的实现特定于实体,并且比类型转换器的实现复杂。 而且,如果需要加密其他属性,则需要更改实现。

如您在上面的示例中所看到的,类型转换器的实现既简单又可重用。 CryptoConverter可以用于加密任何实体的任何String属性。 并且通过使用基于XML的配置将转换器注册到实体属性,它不需要更改应用程序的源代码。 如果迁移现有数据,您甚至可以在以后的某个时间将其添加到应用程序中。 该解决方案的缺点是,加密的实体属性不能标记为瞬态。 如果将实体写入磁盘,则可能会导致漏洞。

您会看到,两种方法都有其优缺点。 您必须决定哪些优点和缺点对您来说更重要。

结论

在本文的开头,我们定义了3个要求:

  • 提供不影响应用程序的透明加密,
  • 能够在部署时添加加密,
  • 由两个不同的团队/人员开发应用程序和安全性/加密。

所描述的CryptoConverter实现实现了所有这些。 如果使用XML配置分配类型转换器,则可以在部署时添加加密,并且不会影响应用程序。 应用程序的开发和加密是完全独立的,可以由不同的团队来完成。 最重要的是,CryptoConverter可用于转换任何实体的任何String属性。 因此具有很高的可重用性。 但是,正如我们在上一段中看到的那样,此解决方案也存在一些缺点。

您必须决定要使用哪种方法。 请给我评论您的选择。

翻译自: https://www.javacodegeeks.com/2014/06/how-to-use-a-jpa-type-converter-to-encrypt-your-data.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go语言的排序和去重

go语言的排序&#xff1a; https://blog.csdn.net/u010983881/article/details/52460998 go语言去重&#xff1a; https://blog.csdn.net/qq_27068845/article/details/77407358 通过构造set去重&#xff08;go中没有set&#xff09;&#xff1a; https://studygolang.com/arti…

MapXtreme2008中操作矢量符号和定制符号

本文部分说明内容摘自网络文章&#xff0c;经过本人在MapXtreme2008中编写相关的演示例子&#xff0c;详细说明如何操作MapXtreme2008提供的矢量符号和定制符号。 MapXtreme 在其安装过程中自动安装 10 种 MapInfo 特定的 TrueType 字体。这些字体为用户提供了字形符号选择&am…

指甲之指甲长期没有甲半月弧(二)

中医的精是构成人体的基本物质。精来源于先天的禀赋及后天饮食营养。中医认为&#xff0c;气不耗归于肝为血&#xff0c;血不耗归于肾为精&#xff0c;精不耗归于骨为髓。 半月痕正是人体精髓的窗口。而半月痕的变化&#xff0c;犹如汽车上的油表一样&#xff0c;它会告颂人体&…

编写干净的测试–从配置开始

很难为干净的代码找到一个好的定义&#xff0c;因为我们每个人都有自己的单词clean的定义。 但是&#xff0c;有一个似乎是通用的定义&#xff1a; 干净的代码易于阅读。 这可能会让您感到有些惊讶&#xff0c;但是我认为该定义也适用于测试代码。 使测试尽可能具有可读性是我…

集合类(二)

关于迭代器&#xff08;Iterator&#xff09;的两种迭代机制&#xff1a;fail-fast 和 fail-safe fail-fast 机制&#xff1a;遍历集合时&#xff0c;当集合结构被修改&#xff0c;会抛出Concurrent Modification Exception 触发条件&#xff1a;单线程在遍历过程修改&#xff…

jQuery-弹幕

该方法可能有bug&#xff0c;毕竟简单粗暴 <!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title></title> <script type"text/javascript" src"js/jquery-1.11.0.js"></script> <s…

ubuntu下C编程,编译基础( 转)

buntu下C编程&#xff0c;编译基础 C 编程中相关文件后缀 .a静态库 (archive).cC源代码&#xff08;需要编译预处理&#xff09;.hC源代码头文件.iC源代码&#xff08;不需编译预处理&#xff09;.o对象文件.s汇编语言代码.so动态库单个源文件生成可执行程序 下面是一个简单的…

转载:97特瑞心得

单位里无聊打着玩的心得&#xff0c;写了段时间了&#xff0c;基本是哪天想到什么就打上去&#xff0c;狗屁不通的地方请大家包涵。97特瑞玩了有10年多了吧,97刚出来的时候就玩的特瑞&#xff0c;别人都八神&#xff0c;萝卜特&#xff0c;克拉克的时代我就坚持用特瑞&#xff…

Hibernate二级/查询缓存的陷阱

这篇文章将介绍如何设置Hibernate二级和查询缓存&#xff0c;它们如何工作以及最常见的陷阱。 休眠二级缓存是用于存储实体数据的应用程序级缓存。 查询缓存是一个单独的缓存&#xff0c;仅存储查询结果。 这两个缓存实际上是并存的&#xff0c;因为在很多情况下&#xff0c;…

C#工厂模式-简单工厂

简单工厂: 工厂模式:简单工厂,工厂方法,抽象工厂三种. 简单工厂(力求简洁) 工厂即为生产东西的地方.在C#也有这种模式,充分利用了面向对象语言的三大特征(多态,继承),简单工厂.工厂的功能就是生产,而生产些什么呢?一个工厂可以生产鞋子,生产衣服.它们所处的车间不一样,所以需…

跨域方式

原文地址&#xff1a;https://www.xingkongbj.com/blog/http/cross-origin.html http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html document.domain iframe 实现父页面与其内部 iframe 页面通讯&#xff0c;要求一级域名相同两个页面设置 document.domain 为相…

Linux学习之四——磁盘与文件系统管理

一、一些基本定义 1. superblock&#xff1a;记录此 filesystem 的整体信息&#xff0c;包括inode/block的总量、使用量、剩余量&#xff0c; 以及文件系统的格式与相关信息等&#xff1b;2. inode&#xff1a;记录档案的属性&#xff0c;一个档案占用一个inode&#xff0c;同时…

使用.Net 1.1的项目,TreeView控件不能正常显示

使用.Net 1.1的项目&#xff0c;TreeView控件不能正常显示&#xff0c;往往是显示一大堆的文字&#xff0c;那是因为脚本没有被执行造成的&#xff0c;需要在web.config里配置一下。<!-- Microsoft WebControls --><MicrosoftWebControls> <add key"Common…

吸气剂/设定者。 邪恶。 期。

从2003年开始&#xff0c;艾伦霍鲁布&#xff08;Allen Holub&#xff09;讨论了为什么吸气剂和塞特方法是邪恶的著名文章&#xff0c;关于吸气剂/塞特方法是否是反模式&#xff0c;应该避免使用&#xff0c;还是我们在面向对象中不可避免地需要它&#xff0c;这是一个古老的争…

你不可不知的数据库northwind

说起northwind&#xff0c;40左右的大年一定不会陌生&#xff0c;它是著名的northwind示例库&#xff0c;在SQL Server 是标配。 它有8张表&#xff0c;涉及客户、商品、订单。 如果你是有志从事企业级应用开发&#xff0c;或有志从事企业互联网开发&#xff0c;一定不要错过no…

angularjs中 $watch 和$on 2种监听的区别?

1.$watch简单使用 $watch是一个scope函数&#xff0c;用于监听模型变化&#xff0c;当你的模型部分发生变化时它会通知你。 $watch(watchExpression, listener, objectEquality); 每个参数的说明如下&#xff1a; watchExpression&#xff1a;监听的对象&#xff0c;它可以是…

【原】.Net创建Excel文件(插入数据、修改格式、生成图表)的方法

1.添加Excel引用 可以在.Net选项卡下添加Microsoft.Office.Interop.Excel引用&#xff0c;或在COM下添加Microsoft Excel 12.0 Object Library。它们都会生成Microsoft.Office.Interop.Excel.dll。 2.创建Excel。 有两种方法创建一个Excel Workbook实例。 1.需要一个模板文件&…

求助:安装程序无法创建一个DCOM用户帐号来注册.....\valec.exe

http://support.microsoft.com/kb/257413/ 这是Visual Studio的一个BUG&#xff0c;只出现在Windows 2000/XP下。如果你不使用Visual Studio Analyzer&#xff0c;可以在安装时选择Custom&#xff0c;然后在Enterprise Tools中清除掉Visual Studio Analyzer。再安…

Spring / Hibernate使用log4jdbc改进了SQL日志记录

Hibernate提供了开箱即用的SQL日志记录&#xff0c;但是这种日志记录仅显示准备好的语句&#xff0c;而不显示发送到数据库的实际SQL查询。 它还不会记录每个查询的执行时间&#xff0c;这对于性能故障排除很有用。 这篇博客文章将介绍如何设置Hibernate查询日志记录&#xff…

快递API接口

快递100 转载于:https://www.cnblogs.com/onesmail/p/10608600.html