小白入门之 Jasypt 加密和解密
Posted 高建伟-joe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小白入门之 Jasypt 加密和解密相关的知识,希望对你有一定的参考价值。
文章目录
摘要
博主写作此文时,该软件的最新版本为:Jasypt 1.9.3 RELEASED
Jasypt 简介
Jasypt 是一个 Java 库,它允许开发人员以最小的努力为项目添加基本的加密功能,而无需深入了解密码学的工作原理。
Jasypt 特征
- Jasypt 提供简单的单向(摘要)和双向加密技术。
- 用于任何 JCE 提供程序的开放 API,而不仅仅是默认的 Java VM 提供程序。 Jasypt 可以很容易地与 Bouncy Castle 等知名提供商一起使用。
- 为您的用户密码提供更高的安全性。
- 二进制加密支持。 Jasypt 允许对二进制文件(字节数组)进行摘要和加密。 在需要时加密您的对象或文件(例如通过网络发送)。
- 数值加密支持。 除了文本和二进制文件,它还允许对数值进行摘要和加密(BigInteger 和 BigDecimal,加密 Hibernate 持久性时支持其他数字类型)。
- 完全线程安全。
- 支持加密/摘要池,以在多处理器/多核系统中实现高性能。
- 包括库的轻量级(“精简”)版本,以便在移动平台等大小受限的环境中具有更好的可管理性。
- 为加密新手提供简单、无需配置的加密工具,也为高级用户提供高度可配置的标准加密工具。
- Hibernate 3、4 和 5 可选集成,用于以加密方式持久化映射实体的字段。 字段加密在 Hibernate 映射文件中定义,它对应用程序的其余部分保持透明(对于敏感的个人数据、具有许多已启用读取的用户的数据库…)。 加密文本、二进制文件、数字、布尔值、日期…
- 无缝集成到 Spring 应用程序中,具有适用于 Spring 2、Spring 3.0、Spring 3.1 和 Spring 4.0 的特定集成功能。 jasypt 中的所有摘要器和加密器都设计为易于从 Spring 使用(实例化、依赖注入…)。 而且,由于它们是线程安全的,因此它们可以在像 Spring 这样的面向单例的环境中使用而无需担心同步问题。
- Spring Security(原Acegi Security)可选集成,用于为安全框架执行密码加密和匹配任务,通过使用更安全的密码加密机制来提高用户密码的安全性,并为您提供更高程度的配置和控制。
- 提供用于加密全部或部分应用程序配置文件的高级功能,包括数据库密码等敏感信息。 将加密配置无缝集成到普通的、基于 Spring 的和/或支持 Hibernate 的应用程序中。
- 提供易于使用的 CLI(命令行界面)工具,允许开发人员初始化他们的加密数据,并在维护任务或脚本中包含加密/解密/摘要操作。
- 集成到 Apache Wicket 中,以在您的安全应用程序中对 URL 进行更强大的加密。
- 全面的指南和 javadoc 文档,使开发人员能够更好地了解他们真正对数据做了什么。
- 强大的字符集支持,旨在充分加密和摘要文本,无论原始字符集是什么。 完全支持日语、韩语、阿拉伯语等语言,没有编码或平台问题。
- 非常高级的配置功能:开发人员可以实施一些技巧,例如指示“加密器”向远程 HTTPS 服务器询问用于加密的密码。 它可以让您满足您的安全需求。
下载 Jasypt
从GitHub下载Jasypt
使用Maven下载Jasypt
Spring Boot 集成 Jasypt
Jasypt 环境依赖要求
Java Virtual Machine
- Jasypt 需要 Java 标准版 1.6 或更高版本。
- 如果您打算使用强加密算法(如 TripleDES),您可能需要下载并安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files
Jasypt 的基本依赖项
- 从 1.7 版开始,jasypt 在与 Java 6 版或更高版本一起使用时不依赖于任何外部库。
- 如果您使用 Java SE 5 或更旧的版本作为较旧的 Jasypt 版本(小于 1.9.3),您将需要:International Components for Unicode (ICU) 3.4.4 或者更高版本。
- 另请注意,从 jasypt 1.8 开始,ICU (icu4j) 将用于规范化 Unicode,如果它存在于类路径中,即使使用 Java >= 6(尽管如此,icu4j 和 java.text.Normalizer 实现是完全兼容的)。
Jasypt 用法
简单用法:utils
使用 Jasypt 的最简单方法是使用其简单的加密工具,称为 utils,因为它们位于 org.jasypt.util 包中。
它们被称为 utils,因为它们是现成的、预先配置的摘要器和加密器,您可以在不了解其配置的情况下使用它们。
这些实用程序根据它们要执行的任务进行分类:
- 一般摘要(org.jasypt.util.digest.*)
- 密码加密(摘要)(org.jasypt.util.password.*)
- 文本加密 (org.jasypt.util.text.*)
- 数字加密 (org.jasypt.util.numeric.*)
- 二进制加密 (org.jasypt.util.binary.*)
提 示 : \\colorred提示: 提示: 请注意,一般来说,当我们谈论“密码加密”时,我们实际上是在谈论“密码摘要”,这是技术上正确的术语。
一般摘要
- org.jasypt.util.digest.Digester 在二进制级别执行消息摘要,其结果等同于从 java.security.MessageDigest 对象获得的结果,尽管以线程安全的方式运行并实现更合适的接口 用于以 bean 为中心的环境。
...
Digester digester = new Digester();
digester.setAlgorithm("SHA-1");
...
byte[] digest = digester.digest(message);
密码加密(摘要)
这里的所有类都实现了 org.jasypt.util.password.PasswordEncryptor 接口,以便它们可以在需要时互换使用。
- org.jasypt.util.password.BasicPasswordEncryptor 可用于在用户注册时加密密码并在用户登录时检查输入密码。
...
BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword))
// correct!
else
// bad login!
...
- org.jasypt.util.password.StrongPasswordEncryptor 实现了比 PasswordEncryptor 更高的密码安全性(计算成本更高)。
...
StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword))
// correct!
else
// bad login!
...
- org.jasypt.util.password.ConfigurablePasswordEncryptor 允许开发人员决定要使用的算法,以及他/她是否想要应用完整的安全密码加密机制(如此处所述),还是为遗留集成生成一个简单的摘要 原因。
...
ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();
passwordEncryptor.setAlgorithm("SHA-1");
passwordEncryptor.setPlainDigest(true);
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword))
// correct!
else
// bad login!
...
文本加密
这里的所有类都实现了 org.jasypt.util.text.TextEncryptor 接口,以便在需要时可以互换使用它们。
- org.jasypt.util.text.BasicTextEncryptor 允许用户使用正常强度算法加密和解密文本数据。 为了能够加密和解密,这个加密器必须先设置密码。
...
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
...
String myEncryptedText = textEncryptor.encrypt(myText);
...
String plainText = textEncryptor.decrypt(myEncryptedText);
...
- org.jasypt.util.text.StrongTextEncryptor 允许用户使用高强度算法加密和解密文本数据。 (您可能需要下载并安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 才能使用它)。 为了能够加密和解密,这个加密器必须先设置密码。
...
StrongTextEncryptor textEncryptor = new StrongTextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
...
String myEncryptedText = textEncryptor.encrypt(myText);
...
String plainText = textEncryptor.decrypt(myEncryptedText);
...
提 示 : \\colorred提示: 提示: 更高的安全性:AES256TextEncryptor 实用程序类具有更安全的算法:PBEWithHMACSHA512AndAES_256,(您至少需要 Java 8 才能使用它):
...
AES256TextEncryptor textEncryptor = new AES256TextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
...
String myEncryptedText = textEncryptor.encrypt(myText);
...
String plainText = textEncryptor.decrypt(myEncryptedText);
...
数值加密
这里的所有类都实现了 org.jasypt.util.numeric.DecimalNumberEncryptor 或 org.jasypt.util.numeric.IntegerNumberEncryptor 接口,以便它们可以在需要时互换使用。
- org.jasypt.util.numeric.BasicIntegerNumberEncryptor 允许用户使用正常强度算法加密和解密 BigInteger 对象。 为了能够加密和解密,这个加密器必须先设置密码。
...
BasicIntegerNumberEncryptor integerEncryptor = new BasicIntegerNumberEncryptor();
integerEncryptor.setPassword(myEncryptionPassword);
...
BigInteger myEncryptedNumber = textEncryptor.encrypt(myNumber);
...
BigInteger plainNumber = textEncryptor.decrypt(myEncryptedNumber);
...
- org.jasypt.util.numeric.StrongIntegerNumberEncryptor 允许用户使用高强度算法加密和解密 BigInteger 对象。 (您可能需要下载并安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 才能使用它)。 为了能够加密和解密,这个加密器必须先设置密码。
...
StrongIntegerNumberEncryptor integerEncryptor = new StrongIntegerNumberEncryptor();
integerEncryptor.setPassword(myEncryptionPassword);
...
BigInteger myEncryptedNumber = integerEncryptor.encrypt(myNumber);
...
BigInteger plainNumber = integerEncryptor.decrypt(myEncryptedNumber);
...
提 示 : \\colorred提示: 提示: 更高的安全性:AES256DecimalNumberEncryptor 实用程序类具有更安全的算法:PBEWithHMACSHA512AndAES_256,(您至少需要 Java 8 才能使用它):
...
BigInteger myNumber = ...;
...
AES256IntegerNumberEncryptor numberEncryptor = new AES256IntegerNumberEncryptor();
numberEncryptor.setPassword(myEncryptionPassword);
...
BigInteger myEncryptedNumber = numberEncryptor.encrypt(myNumber);
...
BigInteger plainNumber = numberEncryptor.decrypt(myEncryptedNumber);
...
- org.jasypt.util.numeric.BasicDecimalNumberEncryptor 允许用户使用正常强度算法加密和解密 BigDecimal 对象。 为了能够加密和解密,这个加密器必须先设置密码。
...
BasicDecimalNumberEncryptor decimalEncryptor = new BasicDecimalNumberEncryptor();
decimalEncryptor.setPassword(myEncryptionPassword);
...
BigDecimal myEncryptedNumber = decimalEncryptor.encrypt(myNumber);
...
BigDecimal plainNumber = decimalEncryptor.decrypt(myEncryptedNumber);
...
- org.jasypt.util.numeric.StrongDecimalNumberEncryptor 允许用户使用高强度算法加密和解密 BigDecimal 对象。 (您可能需要下载并安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 才能使用它)。 为了能够加密和解密,这个加密器必须先设置密码。
...
StrongDecimalNumberEncryptor decimalEncryptor = new StrongDecimalNumberEncryptor();
decimalEncryptor.setPassword(myEncryptionPassword);
...
BigDecimal myEncryptedNumber = decimalEncryptor.encrypt(myNumber);
...
BigDecimal plainNumber = decimalEncryptor.decrypt(myEncryptedNumber);
...
提 示 : \\colorred提示: 提示: 更高的安全性:AES256DecimalNumberEncryptor 实用程序类具有更安全的算法:PBEWithHMACSHA512AndAES_256,(您至少需要 Java 8 才能使用它):
...
BigDecimal myNumber = ...;
...
AES256DecimalNumberEncryptor numberEncryptor = new AES256DecimalNumberEncryptor();
numberEncryptor.setPassword(myEncryptionPassword);
...
BigDecimal myEncryptedNumber = numberEncryptor.encrypt(myNumber);
...
BigDecimal plainNumber = numberEncryptor.decrypt(myEncryptedNumber);
...
二进制加密
这里的所有类都实现了 org.jasypt.util.binary.BinaryEncryptor 接口,以便它们可以在需要时互换使用。
- org.jasypt.util.binary.BasicBinaryEncryptor 允许用户使用正常强度算法加密和解密 byte[] 对象。 为了能够加密和解密,这个加密器必须先设置密码。
...
BasicBinaryEncryptor binaryEncryptor = new BasicBinaryEncryptor();
binaryEncryptor.setPassword(myEncryptionPassword);
...
byte[] myEncryptedBinary = binaryEncryptor.encrypt(myBinary);
...
String plainBinary = binaryEncryptor.decrypt(myEncryptedBinary);
...
- org.jasypt.util.binary.StrongBinaryEncryptor 允许用户使用高强度算法加密和解密 byte[] 对象。 (您可能需要下载并安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 才能使用它)。 为了能够加密和解密,这个加密器必须先设置密码。
...
StrongBinaryEncryptor binaryEncryptor = new StrongBinaryEncryptor();
binaryEncryptor.setPassword(myEncryptionPassword);
...
byte[] myEncryptedBinary = binaryEncryptor.encrypt(myBinary);
...
String plainBinary = binaryEncryptor.decrypt(myEncryptedBinary);
...
提 示 : \\colorred提示: 提示: 更高的安全性:AES256BinaryEncryptor 实用程序类具有更安全的算法:PBEWithHMACSHA512AndAES_256,(您至少需要 Java 8 才能使用它):
...
AES256BinaryEncryptor binaryEncryptor = new AES256BinaryEncryptor();
binaryEncryptor.setPassword(myEncryptionPassword);
...
byte[] myEncryptedBytes = binaryEncryptor.encrypt(myBytes);
...
byte[] plainBytes = binaryEncryptor.decrypt(myEncryptedBytes);
...
一般用法
本节将教您有关 jasypt 为您提供的工具,当在简单使用页面中找到的简单实用程序不足以满足您的需求时。
Digesters
Digesters 是专门用于从输入创建消息摘要(也称为散列)的类。
消息摘要是摘要(或哈希)函数的结果,它们是单向的,也就是说,从消息摘要开始,原始消息无法重构。
因此,消息摘要非常适合密码加密。 事实上,在某些国家/地区,以未加密的方式存储用户密码,甚至以可逆(双向)方式加密都是违法的。
jasypt 中的消化器位于 org.jasypt.digest 包中,该包由以下接口组成:
- ByteDigester 用于从字节数组输入创建摘要。
- StringDigester 用于从字符串输入创建摘要。
以及以下标准实现:
- StandardByteDigester:ByteDigester 的可配置性和极其安全的实现,按照 PKCS #5:基于密码的加密标准中给出的指令实现。
- StandardStringDigester:与 StandardByteDigester 对应的字符串,接收字符串输入并返回字符集安全、BASE64(或十六进制)编码的字符串输出。
及其相应的基于池的实现,可在多处理器/多核系统中实现高性能:
- PooledByteDigester:与 StandardByteDigester 相同的 API,但实际上包含这些对象的池,用于在循环中提供摘要/检查请求。
- PooledStringDigester:与 StandardStringDigester 相同的 API,但实际上包含这些对象的池,用于在循环中提供摘要/检查请求。
使用它们可以非常简单:
...
StandardStringDigester digester = new StandardStringDigester();
digester.setAlgorithm("SHA-1"); // optionally set the algorithm
digester.setIterations(50000); // increase security by performing 50000 hashing iterations
...
String digest = digester.digest(myMessage);
...
这些标准的和池化的摘要器实现了一组连贯且安全的默认配置值,但它们可以通过两种方式进行额外配置:
- 通过调用其 setX(…) 方法(算法、提供者、盐大小等)
- 通过设置一个 DigesterConfig 对象来配置消化器。 提供了此接口的默认 bean 实现 (SimpleDigesterConfig),但用户可以创建他/她自己的实现,以便能够以他/她需要的任何方式检索配置参数。
提高多处理器/多核系统的性能
池化消化器具有与其非池化标准相关的完全相同的 API——因此它们可以互换使用——但添加了一个新的必需配置方法,称为 setPoolSize(),用于确定它们将在内部保留的标准消化器的数量。
...
PooledStringDigester digester = new PooledStringDigester();
digester.setPoolSize(4); // This would be a good value for a 4-core system
digester.setAlgorithm("SHA-1");
digester.setIterations(50000);
...
String digest = digester.digest(myMessage);
...
这些池化对象将使用其内部 Standard* 摘要器以循环方式为请求提供服务,因此由标准工件中的同步代码导致的线程阻塞量减少到最低限度。
这些实现不会创建新线程,因此它们可以安全地用于不允许创建新线程的容器控制环境中。
为特定应用程序和机器推荐的池大小取决于许多因素,但将大致等于机器中处理器/内核的数量。
Encryptors
加密器是专门用于执行双向加密操作的类。 也就是说,它们既可以加密纯数据,也可以解密加密数据。
jasypt 中加密的相关接口位于 org.jasypt.encryption 包中,它们是:
- ByteEncryptor 用于字节数组的加密和解密。
- StringEncryptor 用于字符串的加密和解密。
- BigIntegerEncryptor 用于对 BigInteger 进行加密和解密。
- BigDecimalEncryptor 用于对 BigDecimals 进行加密和解密。
Jasypt 提供了一种加密类型的实现:基于密码的加密 (PBE)。
Password-Based Encryption (PBE)
基于密码的加密是通过从用户提供的密码生成加密密钥,并将输入和生成的密钥提供给加密算法来执行的。 密钥通常是通过对密码应用一些散列函数来获得的。
因此,jasypt 中的所有 PBE 加密器都需要在用于加密或解密操作之前设置密码。
jasypt 中 PBE 的相关接口位于 org.jasypt.encryption.pbe 包中,它们是:
- PBEByteEncryptor 用于字节数组的基于密码的加密和解密。
- PBEStringEncryptor 用于基于密码的字符串加密和解密。
- PBEBigIntegerEncryptor 用于 BigInteger 的基于密码的加密和解密。
- PBEBigDecimalEncryptor 用于 BigDecimals 的基于密码的加密和解密。
以及以下标准实现:
- StandardPBEByteEncryptor:PBEByteEncryptor 的非常可配置且极其安全的实现,按照 PKCS #5:基于密码的加密标准中给出的指令实现。
- StandardPBEStringEncryptor:StandardPBEByteEncryptor 的字符串对应物,接收字符串输入并返回字符集安全、BASE64(或十六进制)编码的字符串输出作为加密结果。
- StandardPBEBigIntegerEncryptor:相当于StandardPBEByteEncryptor,接收BigInteger输入,返回BigInteger输出。
- StandardPBEBigDecimalEncryptor:相当于StandardPBEByteEncryptor,接收BigDecimal 输入并返回BigDecimal 输出。
及其相应的基于池的实现,可在多处理器/多核系统中实现高性能:
- PooledPBEByteEncryptor:与 StandardPBEByteEncryptor 相同的 API,但实际上包含这些对象的池,用于在循环中为加密/解密请求提供服务。
- PooledPBEStringEncryptor:与 StandardPBEStringEncryptor 相同的 API,但实际上包含这些对象的池,用于在循环中为加密/解密请求提供服务。
- PooledPBEBigIntegerEncryptor:与 StandardPBEBigIntegerEncryptor 相同的 API,但实际上包含这些对象的池,用于在循环中提供加密/解密请求。
- PooledPBEBigDecimalEncryptor:与 StandardPBEBigDecimalEncryptor 相同的 API,但实际上包含这些对象的池,用于在循环中为加密/解密请求提供服务。
它的基本用法可以非常简单:
...
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword("jasypt"); // we HAVE TO set a password
encryptor.setAlgorithm("PBEWithHMACSHA512AndAES_256"); // optionally set the algorithm
encryptor.setIvGenerator(new RandomIvGenerator()); // for PBE-AES-based algorithms, the IV generator is MANDATORY
...
String encryptedText = encryptor.encrypt(myText);
...
String plainText = encryptor.decrypt(encryptedText); // myText.equals(plainText)
...
与摘要器一样,标准*加密器实现了一组连贯且安全的默认配置值(密码除外),但它们也可以通过两种方式进行额外配置:
通过调用其 setX(…) 方法(算法、提供者、密码、salt、IV 等…)
通过设置配置消化器的 PBEConfig 对象。 提供了此接口的默认 bean 实现 (SimplePBEConfig),但用户可以创建他/她自己的实现,以便能够以他/她需要的任何方式检索配置参数(例如,从远程服务器检索密码)。
提高多处理器/多核系统的性能
池化加密器与非池化标准相关的 API 完全相同——因此它们可以互换使用——但添加了一个名为 setPoolSize() 的新必需配置方法,该方法建立了它们将在内部保留的标准加密器的数量。
...
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setPoolSize(4); // This would be a good value for a 4-core system
encryptor.setPassword("jasypt");
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");
...
String encryptedText = encryptor.encrypt(myText);
...
这些池化对象将使用其内部 Standard* 加密器以循环方式为请求提供服务,因此由标准工件中的同步代码导致的线程阻塞量减少到最低限度。
这些实现不会创建新线程,因此它们可以安全地用于不允许创建新线程的容器控制环境中。
为特定应用程序和机器推荐的池大小取决于许多因素,但将大致等于机器中处理器/内核的数量。
使用精简版 Jasypt
从命令行加密:Jasypt CLI 工具
Jasypt 提供了一系列命令行界面 (CLI) 工具,可用于从命令行执行加密、解密和摘要操作。
为了使用这个工具,你应该下载分发 zip 文件(名为 jasypt-$VERSION-dist.zip)并解压它。 完成后,您将找到一个 jasypt-$VERSION/bin 目录,其中包含:
- 一组用于 Windows 执行的 .bat 文件:
- encrypt.bat:用于 PBE(基于密码的加密)加密操作。
- decrypt.bat:用于 PBE(基于密码的加密)解密操作。
- digest.bat:用于消息摘要操作。
- listAlgorithms.bat:用于列出 JVM 中可用的摘要和 PBE 加密算法。
- 一组用于 Linux/UNIX 执行的 .sh 文件:
- encrypt.sh:用于 PBE(基于密码的加密)加密操作。
- decrypt.sh:用于 PBE(基于密码的加密)解密操作。
- digest.sh:用于消息摘要操作。
- listAlgorithms.sh:用于列出 JVM 中可用的摘要和 PBE 加密算法。
提 示 : \\colorred提示: 提示: 请注意,在使用 .sh 文件之前,您可能需要使用“chmod u+x *.sh”之类的内容为其添加执行权限。
::这些命令中的大多数都使用以下语法执行:
::[command] [argument1]=[value1] [argument2]=[value2] ...
::For example:
./digest.sh input="U3ERPA33_W0RD" algorithm=SHA1
Extended Classpath:所有这些命令都遵循 JASYPT_CLASSPATH 环境变量的存在,其中包含用于执行加密/解密/摘要命令的扩展类路径定义。 如果用户想要配置他/她自己的安全提供程序或盐生成器实现,或者如果用户使用 Java 1.5 或更早版本并且需要将 icu4j 的 jars 添加到类路径(这些不再包含在 jasypt 的分发中),则此功能非常有用 )。
Verbosity:这些命令中的大多数都接受一个详细参数(可以设置为 true(默认)或 false),它让用户从解释性输出切换到非常简化的输出,只显示操作的结果(对于脚本编写特别有用) )。
Encryption from the command line (“encrypt” command)
在命令行中使用 encrypt.bat/encrypt.sh 命令进行加密,其用法和参数化与 org.jasypt.encryption.pbe.StandardPBEStringEncryptor 的用法和参数化完全一致。 执行 CLI
以上是关于小白入门之 Jasypt 加密和解密的主要内容,如果未能解决你的问题,请参考以下文章
Java库如何使用优秀的加密库Jasypt来保护你的敏感信息?
Springboot yml配置参数加密 ,jasypt自定义解密器