网站建设看什么书,江苏住房和城乡建设厅网站报考,网络服务提供者接到通知后,wordpress微博图床怎么用几天前#xff0c;我读了Bear Giles关于2012年使用JPA监听器进行数据库加密的有趣文章。他讨论了对加密解决方案的要求#xff0c;并提供了JPA监听器的代码示例。 他的主要要求是#xff1a; 提供不影响应用程序的透明加密#xff0c; 能够在部署时添加加密#xff0c; … 几天前我读了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 {IdGeneratedValue(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 AttributeConverterString, 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 version2.1xmlnshttp://xmlns.jcp.org/xml/ns/persistence/ormxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsdentity classblog.thoughts.on.java.jpa21.enc.entity.CreditCardconvert converterblog.thoughts.on.java.jpa21.enc.converter.CryptoConverter attribute-nameccNumber//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