目录

1     Jasypt简介...

2     基础知识回顾...

3     Jasypt+基本加密器...

4     Jasypt+PBE加密器...

5     Jasypt+池化加密器...

6     Jasypt+客户端工具...

7     Jasypt+Springboot基本用法...

8     Jasypt+Springboot自定义加密器...

9     Jasypt+Springboot配置文件加密...

1、Jasypt简介

Jasypt是一个java的加密库,通过对java自带加密算法的二次包装,提供了十分简洁的加密接口,在保证安全的同时,降低了密码算法的使用门槛,并且提供多种数据类型的加密。在Jasypt-spring-boot的加持下,Jasypt可以在Spring应用中轻易集成,充分利用Spring的依赖注入,属性检测等特性。本文提供Jasypt用法的介绍,基本覆盖Jasypt绝大部分的使用场景。

2、基础知识回顾

对称加密(Symmetric encryption):加密和解密用同一个密钥的方法,即为对称加密算法。

哈希算法(Hash):也叫散列、杂凑、摘要,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值,哈希算法是单向算法,即无法通过哈希值倒推原始数据。

口令散列(Password Hashing):是将用户输入的密码通过一系列算法处理后,生成一个固定长度的散列值。口令散列常用语口令存储和密钥生成。在软件系统中,出于安全需求,用户密码不允许直接在数据库中明文存储的,通过对口令做哈希在入库,这样即是数据库泄露了,用户密码依然不会泄露。对于密钥生成的场景,需区分口令和密钥的区别,密钥是指加密过程中实际作用于加密算法的数据串,也叫key,key一般长度较长(16或32字节以上),实际场景中不太可能让用户去设置和记住这么长的密码,因此一般使用用户设置的短密码(也叫口令),用hash算法对口令做散列,用散列出的key加密数据。由于用户口令普遍较短,密码空间较小,重复率比较高,如果数据库发生泄漏,攻击者通过密码和散列值的映射表(又称彩虹表)用于多个用户口令的碰撞,于是在实际散列的时候需加入其它“值”合并计算。该值又称盐或salt,且每个用户的salt都不一样。如果攻击者试图通过彩虹表对口令做碰撞,需要针对每个用户生成口令长度(散列值隐去了实际口令长度)不同的彩虹表,大大增加了破解的难度。口令散列可简化为:hash(口令+salt)

3、Jasypt+基本加密器

1)摘要计算

Digester = new Digester();
digester.setAlgorithm("MD5");
byte[] digest = digester.digest("123".getBytes());
输出:202cb962ac59075b964b07152d234b70

使用外部工具验证,结果符合预期:

Digester仅提供两个setter,setAlgorithm用户设置算法类型,支持的算法类型有:MD2, MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256, SHA3-224, SHA3-256, SHA3-384, SHA3-512,setProvider,设置算法提供的厂商Provider,基本不会用到,缺省即可。

2)密码验证

xxxPasswordEncryptor接口用于密码的加密存储和验证,加密存储即对口令做散列用于存储,验证接口用于用户再次提供口令比对验证,用法如下:

BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
String password= "123456";
String encryptedPassword = passwordEncryptor.encryptPassword(password);
System.out.println(String.format("密文是:%s,输出接口可用于数据库存储", encryptedPassword));
if (passwordEncryptor.checkPassword(password, encryptedPassword)) {System.out.println("口令比对通过!");
} else {System.out.println("口令比对不通过!");
}

Jasypt提供了两个不同算法强度的接口:BasicPasswordEncryptor和StrongPasswordEncryptor,BasicPasswordEncryptor基于MD5,StrongPasswordEncryptor基于SHA-256,使用方法一致。

3)文本加密

Jasypt提供了不同强度的文本(String)加密接口,根据强度排序依次为:
  1. BasicTextEncryptor(PBEWithMD5AndDES)
  2. StrongTextEncryptor (PBEWithMD5AndTripeDES)
  3. AES256TextEncryptor (PBEWithHMACSHA512AndAES_256)

使用方法均为:先调用setPassword设置密码,再调用encrypt或decrypt做加解密(其他加密器的使用替换BasicTextEncryptor类型即可):

BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("passwd");
String myEncryptedText = textEncryptor.encrypt("123456");
System.out.println(myEncryptedText);
String plainText = textEncryptor.decrypt(myEncryptedText);
System.out.println(plainText);

4)二进制加密

二进制加密和文本加密的区别仅在于入参不同,其他基本一致,根据算法强度二进制加密提供如下接口:
  1. BasicBinaryEncryptor (PBEWithMD5AndDES)
  2. StrongBinaryEncryptor (PBEWithMD5AndTripeDES)
  3. AES256TextEncryptor (PBEWithHMACSHA512AndAES_256)
基本用法为:
BasicBinaryEncryptor binaryEncryptor = new BasicBinaryEncryptor();
binaryEncryptor.setPassword("passwd");
byte[] bytes = {'1', '2', '3'};
byte[] myEncryptedByte = binaryEncryptor.encrypt(bytes);
System.out.println(String.format("加密后的密文是:%s",Base64.getEncoder().encodeToString(myEncryptedByte)));
byte[] plainText = binaryEncryptor.decrypt(myEncryptedByte);
System.out.println(String.format("解密后的明文是:%s", new String(plainText)));
输出:
加密后的密文是:1a8117840c945323dc91a7ecf09583bd
解密后的明文是:123

5)数值加密

    Jasypt提供了BigInteger和BigDecimal类型数据的加密接口,此类型加密器使用较少,本文不做详细介绍,基本用法如下:
BigInteger myNumber = new BigInteger("123");
BasicIntegerNumberEncryptor numberEncryptor = new BasicIntegerNumberEncryptor();
numberEncryptor.setPassword("passwd");
BigInteger encryptMyNumber = numberEncryptor.encrypt(myNumber);
System.out.println(String.format("加密后的密文是:%d", encryptMyNumber));
BigInteger decryptMyNumber = numberEncryptor.decrypt(encryptMyNumber);
System.out.println(String.format("解密后的明文是:%d", decryptMyNumber));
输出:
加密后的密文是:442164205133206440127638602826610783717381111824
解密后的明文是:123

4、Jasypt+PBE加密器

    PBE,基于口令的密码运算,即在实际加密前,先用用户口令散列出加密key,再用key做加解密运算。上节中所涉及的接口均为Jasypt PBE算法的包装类,旨在隐去一些不常用的细节,为用户提供简洁的接口。Jasypt提供四个不同类型的PBE加密器,均以StandardPBE<类型>Encryptor命名,通过追踪调用链可发现,这4个不同类型的加密器中,以StandardPBEByteEncryptor为基本接口,这也容易理解,程序计算的基本单位是字节,不管什么数据类型,最终都得转为字节类型再做运算,下列仅以StandardPBEByteEncryptor做举例:
StandardPBEStringEncryptor = new StandardPBEStringEncryptor();
standardPBEStringEncryptor.setPassword("passwd");
String cihperText = standardPBEStringEncryptor.encrypt("123456");
System.out.println(String.format("StandardPBEStringEncryptor的加密结果:%s", cihperText));
BasicTextEncryptor = new BasicTextEncryptor();
basicTextEncryptor.setPassword("passwd");
System.out.println(String.format("basicTextEncryptor的解密结果:%s", basicTextEncryptor.decrypt(cihperText)));
输出:
StandardPBEStringEncryptor的加密结果:ZCWgTEa2pWGXPnI23NFI8Q==
basicTextEncryptor的解密结果:123456
StandardPBEByteEncryptor的配置项如下:
PBEWITHHMACSHA1ANDAES_128
PBEWITHHMACSHA1ANDAES_256
PBEWITHHMACSHA224ANDAES_128
PBEWITHHMACSHA224ANDAES_256
PBEWITHHMACSHA256ANDAES_128
PBEWITHHMACSHA256ANDAES_256
PBEWITHHMACSHA384ANDAES_128
PBEWITHHMACSHA384ANDAES_256
PBEWITHHMACSHA512ANDAES_128
PBEWITHHMACSHA512ANDAES_256
PBEWITHMD5ANDDES
PBEWITHMD5ANDTRIPLEDES
PBEWITHSHA1ANDDESEDE
PBEWITHSHA1ANDRC2_128
PBEWITHSHA1ANDRC2_40
PBEWITHSHA1ANDRC4_128
PBEWITHSHA1ANDRC4_40

PBE接口均提供了以下settter:

1)  setAlgorithm

设置算法,缺省为PBEWithMD5AndDES,可选算法有:

2)setPassword

设置密码,不可缺省

3)setKeyObtentionIterations

设置口令散列的迭代次数,缺省为1000

4)setSaltGenerator

设置盐的生成器,缺省为org.jasypt.salt.RandomSaltGenerator,也是对JCE提供的随机数生成器的二次包装

5)setIvGenerator

用于生成IV(Initial vector)值用于CBC、CFB等其他需要初始向量的加密模式,IV生成器的本质也是随机数生成器,缺省为org.jasypt.iv.RandomIvGenerator,也是对JCE提供的随机数生成器的二次包装

6)setProviderName

设置JCE的Provider,默认是SunJCE。

对于不需要特别定制的场景,使用PBE接口仍可以保持和上节中的加密接口一样间接的使用方式,在使用前仅配置密码,其他项均保持缺省。

5、Jasypt+池化加密器

    Jasypt引入了池化加密器的概念,旨在提高在多核处理器下的计算性能。在应用程序中频繁使用加密和解密操作时,每次创建和销毁加密器实例都会带来一定的性能开销。为了避免这种开销,Jasypt将多个加密器实例保存在一个池,按需从池中获取加密器实例并重复使用。这种方式可以避免重复创建和销毁加密器实例,提高应用程序的性能。Jasypt的方法均为线程安全方法,但是StandardPBEByteEncryptor的encrytor和decryptor中存在线程同步代码,这意味着如果多个线程同时使用一个加密器,存在同步竞争问题,影响系统性能,所以Jasypt池化加密器的本质是通过池化为并发下的每个线程提供不同的加密器,避免竞争问题。应用需自己保证池化的加密器为单例模式。

Jasypt对PBE接口均实现了相应的池化,命名格式为PooledPBE<类型>Encryptor,使用方法除了多了个setPoolSize,其他配置完全一样。setPoolSize建议和CPU核心数一样或略高于核心数,示例代码如下:

// pooledPBEStringEncryptor 全局变量
PooledPBEStringEncryptor = new PooledPBEStringEncryptor();
pooledPBEStringEncryptor.setPoolSize(4);
pooledPBEStringEncryptor.setPassword("passwd");
String cihperText = pooledPBEStringEncryptor.encrypt("123456");
System.out.println(String.format("PooledPBEStringEncryptor的加密结果:%s", cihperText));//使用基本接口对池化的计算接口做验证
BasicTextEncryptor = new BasicTextEncryptor();
basicTextEncryptor.setPassword("passwd");
System.out.println(String.format("BasicTextEncryptor的解密结果:%s", basicTextEncryptor.decrypt(cihperText)));
输出:
PooledPBEStringEncryptor的加密结果:D0rSSuL79lNooMEyHRdB/g==
basicTextEncryptor的解密结果:123456

6、Jasypt+客户端工具

    Jasypt提供了客户端工具可直接用于加密运算,下载地址:链接。解压后的bin的目录为Jasypt客户端工具脚本,工具包包含加密、解密和摘要计算脚本,脚本的本质均为调用Jasypt依赖包下的指定类完成密码运算。直接运行相关脚本可查看帮助信息:

下面使用客户端工具做数据加密,并使用代码对结果做解密验证:

客户端工具默认使用BasicTextEncryptor加密器,因此可用代码做验证:

BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword("passwd");
String myEncryptedText = textEncryptor.decrypt("8zfUPVd/ruyBC3Ah4lRziQ==");
System.out.println(String.format("解密结果为:%s", myEncryptedText) );
输出:
解密结果为:123456

结果符合预期。

下面是用客户端工具做摘要计算的验证过程:

输出结果为base64编码,对输出做base64解码后并以HEX格式显示时,实际结果为:

当盐的长度为0,迭代次数为1(默认为1000)时,等同于一次普通的摘要计算,因此可以使用其他MD5工具对结果做验证比对:

结果符合预期。

7、Jasypt+Springboot基本用法

使用starter完成引入:
<dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>3.0.5</version>
</dependency>
    jasypt-spring-boot是Jasypt的springboot框架,引入框架之后即可根据配置自动注入相应的加密器,该框架还提供属性检测功能,可用于敏感配置的加密,在使用的时候自动完成解密。Jasypt-spring-boot基本配置如下:

Key

Required

Default Value

jasypt.encryptor.password

TRUE

 

jasypt.encryptor.algorithm

FALSE

PBEWITHHMACSHA512ANDAES_256

jasypt.encryptor.key-obtention-iterations

FALSE

1000

jasypt.encryptor.pool-size

FALSE

1

jasypt.encryptor.provider-name

FALSE

SunJCE

jasypt.encryptor.provider-class-name

FALSE

null

jasypt.encryptor.salt-generator-classname

FALSE

org.jasypt.salt.RandomSaltGenerator

jasypt.encryptor.iv-generator-classname

FALSE

org.jasypt.iv.RandomIvGenerator

jasypt.encryptor.string-output-type

FALSE

base64

jasypt.encryptor.proxy-property-sources

FALSE

FALSE

jasypt.encryptor.skip-property-sources

FALSE

empty list

     以上配置除了后面两项,其他配置和PBExxx类的setter方法基本一致。其中jasypt.encryptor.password为必须用户指定,其他配置均提供缺省值,algorithm的缺省配置弃用PBExxx默认的PBEWithMD5AndDES,改为强度更高的PBEWITHHMACSHA512ANDAES_256, 因此对Springboot中的加密结果做Jasypt手工解密时,需同时做password和algorithm的配置。下面案例展示使用默认数据加密,并使用Jasypt“原生”接口做解密验证:
application.properties添加配置:
jasypt.encryptor.password=passwd@Autowired
StringEncryptor;String cypherText = stringEncryptor.encrypt("123456");
System.out.println(String.format("密文为:%s", cypherText));
输出:
密文为:iw7cURRMFU2Wl7/k31mG0Sn8CVjdJ10xu4cb9vodOjbB7efNLui3CI6xgv4DSItY
使用“原生”接口对输出做解密:
AES256TextEncryptor textEncryptor = new AES256TextEncryptor();
textEncryptor.setPassword("passwd");
String myEncryptedText = textEncryptor.decrypt("iw7cURRMFU2Wl7/k31mG0Sn8CVjdJ10xu4cb9vodOjbB7efNLui3CI6xgv4DSItY");
System.out.println(String.format("解密结果为:%s", myEncryptedText) );
输出:
解密结果为:123456

8、Jasypt+Springboot自定义加密器

Jasypt-spring-boo默认注入StringEncryptor加密器的bean-id为”jasyptStringEncryptor”,如需覆盖该加密器,只需在配置类中重新声明新的类型为StringEncryptor且bean-id为”jasyptStringEncryptor”的加密器即可,jasypt-spring-boot-starter通过是否已存在该名称的bean决定是否注入默认的加密器,案例如下:
//添加配置类
@Configuration
public class JasyptConfig {@Bean(name="jasyptStringEncryptor")@Primarystatic public StringEncryptor stringEncryptor() {StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();encryptor.setPassword("passwd");encryptor.setAlgorithm("PBEWITHMD5ANDDES");return encryptor;}
}
输出:
加密结果为:H3QMRyMGPNzYW8QcdhFg1w==
解密结果为:123456
从加密结果长度可看出,@Autowired注入的为自定义的加密器,结果符合预期。自定义加密器仅要求返回StringEncryptor接口,如果开发者需要实现自己的加密算法,只需要实现该接口即可。

9、Jasypt+Springboot配置文件加密

jasypt-spring-boot提供属性检测的功能,对于配置文件的配置项,如果符合jasypt-spring-boot指定的规则,则会自动解密还原为明文注入到对应的代码中,默认规则为ENC(),举例:
//配置文件为
jasypt.encryptor.password=passwd
my.password=ENC(H3QMRyMGPNzYW8QcdhFg1w==)@Value("${my.password:}")private String password;
System.out.println(String.format("my.password:%s", password));
输出:
my.password: 123456
为避免jasypt.encryptor.password本文直接写在配置文件里,jasypt-spring-boot允许通过环境变量或启动参数传入所以配置,因此可以通过环境变量隐藏口令,步骤如下:
启动前:
export jasypt.encryptor.password=xxx启动应用:
java -jar xxx.jar待应用java完成配置注入后,删除环境变量:
export jasypt.encryptor.password=

												

Jasypt加密库基本使用方法相关推荐

  1. 使用Jasypt加密spring boot应用配置文件的敏感信息

    Jasypt是一个Java库,允许开发人员以很简单的方式添加基本加密功能,而无需深入研究加密原理.利用它可以实现高安全性的,基于标准的加密技术,无论是单向和双向加密.加密密码,文本,数字,二进制文件. ...

  2. MD5、AES、Jasypt加密方式的简要介绍与对比

    MD5.AES.Jasypt加密方式的简要介绍与对比 1 前言 目前做的项目中用的加密工具有:MD5.AES加密工具(旧的)及Jasypt加密工具(新增),对这三种加密工具的简要原理和应用做了整理.内 ...

  3. python加密库用哪个好_Python的加密库入门!

    image 加密你的数据并使其免受攻击者的攻击. 密码学俱乐部的第一条规则是:永远不要自己 发明 密码系统.密码学俱乐部的第二条规则是:永远不要自己 实现 密码系统:在现实世界中,在 实现 以及设计密 ...

  4. 【下载】RSA1024及RSA2048加密算法漏洞CVE-2017-7526 问题出在GnuPG加密库

    专家通过对RSA密钥发起侧信道攻击,可破解GnuPG加密库的RSA-1024加密算法.安全研究人员近期发现了一个严重漏洞.该编号为CVE-2017-7526的漏洞存在于隐私保护软件GnuPG(也称为G ...

  5. 【Python包】安装teradatasql提示找不到pycryptodome模块错误(pycrypto,pycryptodome和crypto加密库)...

     1.问题描述 安装teradatasql时,出现错误Could not find a version that satisfies the requirement pycryptodome,具体如下 ...

  6. 理解AES加密解密的使用方法

    很多人对于AES加密并不是很了解,导致互相之间进行加密解密困难. 本文用简单的方式来介绍AES在使用上需要的知识,而不涉及内部算法.最后给出例子来帮助理解AES加密解密的使用方法. AES的麻烦 相比 ...

  7. bfv同态加密_lattigo: 基于Lattice代数结构的Go同态加密库

    Lattigo 基于Lattice代数结构的Go同态加密库 Lattigo是一个Go软件包,实现了基于格的加密原语.该库功能: 纯Go实施,带来代码简单性和易于构建. 一个有效的多精度多项式算术层的公 ...

  8. Mozilla 修复跨平台加密库 NSS 中的严重漏洞

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 Mozilla 修复了影响跨平台网络安全服务 (NSS) 加密库中一个严重的内存损坏漏洞 (CVE-2021-43527). NSS 可用于开发 ...

  9. Bouncy Castle 加密库修复高危的认证绕过漏洞

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 最近,Bouncy Castle 加密库修复了一个高危的认证绕过漏洞. 该项目建立于2000年,表示 Java 和 C# 加密中使用的 ...

最新文章

  1. php中删除数组元素的函数,php删除数组中的元素函数用法汇总
  2. Python学习笔记之六:在VS中调用Python
  3. java 默认参数 实例化_如何使用Kotlin中的默认构造函数参数值实例化对象?
  4. codevs1079 回家
  5. zip unzip_zip和unzip上的Java要点
  6. 详细解析堆排序java实现
  7. python博弈论代码_博弈论(示例代码)
  8. 计算机软件如何永久删除,如何彻底删除电脑软件
  9. excel文档加密破解,简单操作亲测有效
  10. 计算机三维成像在哪些领域有运用,【图】三维动画类别及运用领域,三维动画分类介绍...
  11. 优秀开源项目(持续更新)
  12. 马云卸任阿里董事局主席,有才网友脑洞大开杜撰马云版《出师表》
  13. 【千律】C++基础:删除只读属性文件、文件剪切、修改文件扩展名
  14. 三人行-有分享才会有行动
  15. 论文编辑与投稿——word另存PDF显示“错误!未找到引用源”的解决方案
  16. 用Java模拟一个银行ATM系统
  17. flink sql 连接kafka avro序列化异常 Failed to deserialize Avro record ArrayIndexOutOfBoundsException
  18. 剑指offer16. 数值的整数次方P110
  19. c语言写台球游戏,OpenGL版 3D台球 (原创,Basic实现) 申精!
  20. 向量空间模型——计算文本(英文)相似度

热门文章

  1. 阳光动力2号能够环球航行而不能周游世界
  2. @OneToOne实例详解
  3. 如何短期通过PMP项目管理考试?
  4. asp作品借书网 asp.net期末作品ASP.NET简单图书管理系统
  5. linux 中切换用户指令,Linux中的Su命令(切换用户)
  6. 【JavaScript】js中内存泄漏的几种情况?
  7. 人工智能成了婚姻专家,听听你俩对话的语气就知道会不会离婚
  8. [mysql] 命令行大全
  9. Js算法_买卖股票问题
  10. Java-异或运算详解