聊聊Jasypt的StandardPBEByteEncryptor

本文主要研究一下Jasypt的StandardPBEByteEncryptor

Jasypt

Jasypt即Java Simplified Encryption,它主要是简化项目加解密的工作,内置提供了很多组件的集成,比如hibernate、spring、spring-security等

示例

示例1

StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(userPassword);
...
if (passwordEncryptor.checkPassword(inputPassword, encryptedPassword)) {// correct!
} else {// bad login!
}

示例2

AES256TextEncryptor textEncryptor = new AES256TextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
String myEncryptedText = textEncryptor.encrypt(myText);
...
String plainText = textEncryptor.decrypt(myEncryptedText);

StandardPBEByteEncryptor

org/jasypt/encryption/pbe/StandardPBEByteEncryptor.java

public final class StandardPBEByteEncryptor implements PBEByteCleanablePasswordEncryptor {/*** The default algorithm to be used if none specified: PBEWithMD5AndDES.*/public static final String DEFAULT_ALGORITHM = "PBEWithMD5AndDES";/*** The default number of hashing iterations applied for obtaining the encryption key from the specified password,* set to 1000.*/public static final int DEFAULT_KEY_OBTENTION_ITERATIONS = 1000;/*** The default salt size, only used if the chosen encryption algorithm is not a block algorithm and thus block size* cannot be used as salt size.*/public static final int DEFAULT_SALT_SIZE_BYTES = 8;/*** The default IV size*/public static final int IV_SIZE_IN_BITS = 128;// Algorithm (and provider-related info) for Password Based Encoding.private String algorithm = DEFAULT_ALGORITHM;private String providerName = null;private Provider provider = null;// Password to be applied. This will NOT have a default value. If none// is set during configuration, an exception will be thrown.private char[] password = null;// Number of hashing iterations to be applied for obtaining the encryption// key from the specified password.private int keyObtentionIterations = DEFAULT_KEY_OBTENTION_ITERATIONS;// SaltGenerator to be used. Initialization of a salt generator is costly,// and so default value will be applied only in initialize(), if it finally// becomes necessary.private SaltGenerator saltGenerator = null;// IVGenerator to initialise IVprivate IVGenerator ivGenerator = null;// Size in bytes of the IV to be usedprivate final int IVSizeBytes = IV_SIZE_IN_BITS;// Size in bytes of the salt to be used for obtaining the// encryption key. This size will depend on the PBE algorithm being used,// and it will be set to the size of the block for the specific// chosen algorithm (if the algorithm is not a block algorithm, the// default value will be used).private int saltSizeBytes = DEFAULT_SALT_SIZE_BYTES;//......
}    

StandardPBEByteEncryptor实现了PBEByteCleanablePasswordEncryptor接口,而该则集成了PBEByteEncryptor和CleanablePasswordBased接口,PBEByteEncryptor继承了ByteEncryptor、PasswordBased

ByteEncryptor

org/jasypt/encryption/ByteEncryptor.java

public interface ByteEncryptor {/*** Encrypt the input message* * @param message the message to be encrypted* @return the result of encryption*/public byte[] encrypt(byte[] message);/*** Decrypt an encrypted message* * @param encryptedMessage the encrypted message to be decrypted* @return the result of decryption*/public byte[] decrypt(byte[] encryptedMessage);}

ByteEncryptor定义了encrypt和decrypt方法

StandardPBEByteEncryptor.encrypt

    public byte[] encrypt(final byte[] message) throws EncryptionOperationNotPossibleException {if (message == null) {return null;}// Check initializationif (!isInitialized()) {initialize();}try {final byte[] salt;byte[] iv = null;final byte[] encryptedMessage;if (usingFixedSalt) {salt = fixedSaltInUse;synchronized (encryptCipher) {encryptedMessage = encryptCipher.doFinal(message);}}else {// Create saltsalt = saltGenerator.generateSalt(saltSizeBytes);// Create the IViv = ivGenerator.generateIV(IVSizeBytes);IvParameterSpec ivParameterSpec = null;if (iv != null) {ivParameterSpec = new IvParameterSpec(iv);}/** Perform encryption using the Cipher*/final PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, keyObtentionIterations,ivParameterSpec);synchronized (encryptCipher) {encryptCipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);encryptedMessage = encryptCipher.doFinal(message);}}byte[] encryptedMessageWithIV = encryptedMessage;if (ivGenerator.includePlainIVInEncryptionResults()) {encryptedMessageWithIV = CommonUtils.appendArrays(iv, encryptedMessage);}// Finally we build an array containing both the unencrypted salt// and the result of the encryption. This is done only// if the salt generator we are using specifies to do so.if (saltGenerator.includePlainSaltInEncryptionResults()) {// Insert unhashed salt before the encryption resultfinal byte[] encryptedMessageWithIVAndSalt = CommonUtils.appendArrays(salt, encryptedMessageWithIV);return encryptedMessageWithIVAndSalt;}return encryptedMessageWithIV;}catch (final InvalidKeyException e) {// The problem could be not having the unlimited strength policies// installed, so better give a usefull error message.handleInvalidKeyException(e);throw new EncryptionOperationNotPossibleException();}catch (final Exception e) {// If encryption fails, it is more secure not to return any// information about the cause in nested exceptions. Simply fail.throw new EncryptionOperationNotPossibleException();}}

StandardPBEByteEncryptor的encrypt方法,该方法首先判断salt值是固定的和动态的,固定的则是初始化的时候就设置好的,直接从实例属性取,然后直接调用cipher加密
而动态的话,则通过saltGenerator和generateIV来生成salt和iv,之后根据salt、iv和keyObtentionIterations来创建PBEParameterSpec,然后初始化cipher再进行加密
最后通过ivGenerator判断是否需要把iv包含到加密结果中,是则append到前面进去,再通过saltGenerator判断是否应该把slat包含到加密结果中,是则append到前面进去,最后返回解密结果

StandardPBEByteEncryptor.decrypt

    public byte[] decrypt(final byte[] encryptedMessage) throws EncryptionOperationNotPossibleException {if (encryptedMessage == null) {return null;}// Check initializationif (!isInitialized()) {initialize();}if (saltGenerator.includePlainSaltInEncryptionResults()) {// Check that the received message is bigger than the saltif (encryptedMessage.length <= saltSizeBytes) {throw new EncryptionOperationNotPossibleException();}}// if (this.ivGenerator.includePlainIVInEncryptionResults()) {// // Check that the received message is bigger than the IV// if (encryptedMessage.length <= this.IVSizeBytes) {// throw new EncryptionOperationNotPossibleException();// }// }try {// If we are using a salt generator which specifies the salt// to be included into the encrypted message itself, get it from// there. If not, the salt is supposed to be fixed and thus the// salt generator can be safely asked for it again.byte[] salt = null;byte[] encryptedMessageKernel = null;if (saltGenerator.includePlainSaltInEncryptionResults()) {final int saltStart = 0;final int saltSize = saltSizeBytes < encryptedMessage.length ? saltSizeBytes : encryptedMessage.length;final int encMesKernelStart = saltSizeBytes < encryptedMessage.length ? saltSizeBytes: encryptedMessage.length;final int encMesKernelSize = saltSizeBytes < encryptedMessage.length? encryptedMessage.length - saltSizeBytes: 0;salt = new byte[saltSize];encryptedMessageKernel = new byte[encMesKernelSize];System.arraycopy(encryptedMessage, saltStart, salt, 0, saltSize);System.arraycopy(encryptedMessage, encMesKernelStart, encryptedMessageKernel, 0, encMesKernelSize);}else if (!usingFixedSalt) {salt = saltGenerator.generateSalt(saltSizeBytes);encryptedMessageKernel = encryptedMessage;}else {// this.usingFixedSalt == truesalt = fixedSaltInUse;encryptedMessageKernel = encryptedMessage;}// Logic for IVbyte[] finalEncryptedMessage;byte[] iv;if (ivGenerator.includePlainIVInEncryptionResults()) {// Extracting the IViv = Arrays.copyOfRange(encryptedMessageKernel, 0, IVSizeBytes / 8);finalEncryptedMessage = Arrays.copyOfRange(encryptedMessageKernel, iv.length,encryptedMessageKernel.length);}else {// Fixed IVfinalEncryptedMessage = encryptedMessageKernel;iv = ivGenerator.generateIV(IVSizeBytes);}final byte[] decryptedMessage;if (usingFixedSalt) {/** Fixed salt is being used, therefore no initialization supposedly needed*/synchronized (decryptCipher) {decryptedMessage = decryptCipher.doFinal(encryptedMessageKernel);}}else {/** Perform decryption using the Cipher*/IvParameterSpec ivParameterSpec = null;if (iv != null) {ivParameterSpec = new IvParameterSpec(iv);}final PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, keyObtentionIterations,ivParameterSpec);synchronized (decryptCipher) {decryptCipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);decryptedMessage = decryptCipher.doFinal(finalEncryptedMessage);}}// Return the resultsreturn decryptedMessage;}catch (final InvalidKeyException e) {// The problem could be not having the unlimited strength policies// installed, so better give a usefull error message.handleInvalidKeyException(e);throw new EncryptionOperationNotPossibleException();}catch (final Exception e) {// If decryption fails, it is more secure not to return any// information about the cause in nested exceptions. Simply fail.throw new EncryptionOperationNotPossibleException();}}

StandardPBEByteEncryptor的decrypt方法先通过saltGenerator判断salt是否包含在密文中,是则根据配置的salt的长度从密文取出来salt,之后通过ivGenerator判断iv是否包含在密文中,是则从剩下的密文取出来iv,得到slat和iv之后,对剩下的密文进行解密

小结

StandardPBEByteEncryptor实现了ByteEncryptor的encrypt和decrypt方法,其主要思路就是判断slat、iv是否包含在密文,然后做对应的处理。

doc

  • Jasypt

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

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

相关文章

【高危】Apache Airflow Spark Provider 反序列化漏洞 (CVE-2023-40195)

zhi.oscs1024.com​​​​​ 漏洞类型反序列化发现时间2023-08-29漏洞等级高危MPS编号MPS-qkdx-17bcCVE编号CVE-2023-40195漏洞影响广度广 漏洞危害 OSCS 描述Apache Airflow Spark Provider是Apache Airflow项目的一个插件&#xff0c;用于在Airflow中管理和调度Apache Spar…

QT使用QXlsx实现数据验证与Excel公式操作 QT基础入门【Excel的操作】

准备环境:QT中使用QtXlsx库的三种方法 1、公式操作写单行公式 //右值初始化Format rAlign;rAlign.setHorizontalAlignment(Format::AlignRight);//左值初始化Format lAlign;lAlign.setHorizontalAlignment(Format::AlignLeft);xlsx.write("B3", 40, lAlign);xlsx.wr…

Spark及其生态简介

一、Spark简介 Spark 是一个用来实现快速而通用的集群计算的平台&#xff0c;官网上的解释是&#xff1a;Apache Spark™是用于大规模数据处理的统一分析引擎。 Spark 适用于各种各样原先需要多种不同的分布式平台的场景&#xff0c;包括批处理、迭代算法、交互式查询、流处理…

Generated Knowledge Prompting for Commonsense Reasoning

本文是知识图谱系列相关的文章&#xff0c;针对《Generated Knowledge Prompting for Commonsense Reasoning》的翻译。 常识推理的生成知识提示 摘要1 引言2 生成知识提示3 实验设置4 实验结果5 相关工作6 结论 摘要 结合外部知识是否有利于常识推理&#xff0c;同时保持预训…

如何理解attention中的Q、K、V?

y直接用torch实现一个SelfAttention来说一说&#xff1a; 1、首先定义三哥线性变换&#xff0c;query&#xff0c;key以及value&#xff1a; class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size)#输入768&#xff0c;输出768…

Oracle Scheduler中日期表达式和PLSQL表达式的区别

参考文档&#xff1a; Database Administrator’s Guide 29.4.5.4 Differences Between PL/SQL Expression and Calendaring Syntax Behavior There are important differences in behavior between a calendaring expression and PL/SQL repeat interval. These differenc…

螺旋矩阵、旋转矩阵、矩阵Z字打印

螺旋矩阵 #include <iostream> #include <vector> void display(std::vector<std::vector<int>>&nums){for(int i 0; i < nums.size(); i){for(int j 0; j < nums[0].size(); j){std::cout<<nums[i][j]<< ;}std::cout<<…

从钉钉到金蝶云星空通过接口配置打通数据

从钉钉到金蝶云星空通过接口配置打通数据 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团打造的企业级智能移动办公平台&#xff0c;是数字经济时代的企业组织协同办公和应用开发平台。钉钉将IM即时沟通、钉钉文档、钉闪会、钉盘、Teambition、OA审批、智能…

v-on 和 v-bind

v-on 和 v-bind 都可以与回调函数一起使用&#xff0c;但它们的作用不同。 v-on&#xff1a; 这是Vue中用于绑定事件监听器的指令。你可以使用 v-on 来监听元素的各种事件&#xff08;如点击、输入、鼠标移动等&#xff09;&#xff0c;并在事件触发时执行指定的回调函数。所以…

算法通过村第五关-队列和Hash青铜笔记|队列和Hash

文章目录 前言1. Hash基础1.1 Hash的概念和基本特征1.2 碰撞处理方法1.2.1 开放地址法1.1.2 链地址法 2. 队列的基础2.1 队列的概念和基本特征2.2 队列的实现 总结 前言 提示&#xff1a;幸福的秘密是尽量扩大自己的兴趣范围对感兴趣的人和物尽可能的友善 --波特兰罗素 谈完栈&…

说说Omega架构

分析&回答 Omega架构我们暂且称之为混合数仓。 什么是ECS设计模式 在谈我们的解法的时候&#xff0c;必须要先提ECS的设计模式。 简单的说&#xff0c;Entity、Component、System分别代表了三类模型。 实体(Entity)&#xff1a;实体是一个普通的对象。通常&#xff0c…

在window上安装hadoop3.3.4

暑假不知道啥原因电脑死机啦。环境需要重新配一下 首先需要配置Hadoop集群&#xff0c;但是为了代码调试方便需要先在Windows上配置Hadoop环境。 1.前期准备 首先在搭建Hadoop环境之前需要先安装JDK&#xff0c;并且配置好Java环境变量。 这里有个bug就是Java环境变量中不允许…

视频动态壁纸 Dynamic Wallpaper for Mac中文

Dynamic Wallpaper是一款Mac平台上的动态壁纸应用程序&#xff0c;它可以根据时间等因素动态切换壁纸&#xff0c;提供更加生动和多样化的桌面体验。 Dynamic Wallpaper包含了多个动态壁纸&#xff0c;用户可以根据自己的喜好选择和切换。这些动态壁纸可以根据时间等因素进行自…

【Android Framework系列】第13章 SVG矢量图形自定义组件(绘制中国地图)

1 前言 本章节我们来了解下什么是SVG矢量图形&#xff0c;怎么通过SVG实现图形的绘制&#xff0c;通过SVG实现不规则的自定义控件&#xff0c;项目实现一个中国地图&#xff0c;实现每个省都能够点击&#xff0c;项目地址在文末请自取。 2 SVG概念 2.1 SVG矢量图形 SVG 指可…

二叉树的构建及遍历

目录 题目题目要求示例 解答方法一、实现思路时间复杂度和空间复杂度代码 方法二、实现思路时间复杂度和空间复杂度代码 题目 二叉树的构建及遍历 题目要求 题目链接 示例 解答 方法一、 先构建二叉树&#xff0c;再中序遍历。 实现思路 按照给出的字符串创建二叉树&am…

分布式定时任务框架选型,讲的太好了

1. 前言 我们先思考下面几个业务场景的解决方案: 支付系统每天凌晨1点跑批&#xff0c;进行一天清算&#xff0c;每月1号进行上个月清算电商整点抢购&#xff0c;商品价格8点整开始优惠12306购票系统&#xff0c;超过30分钟没有成功支付订单的&#xff0c;进行回收处理商品成…

Elasticsearch集群内的原理

一个运行中的 Elasticsearch 实例称为一个 节点&#xff0c;而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成&#xff0c; 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时&#xff0c;集群将会重新平均分布所有的数据。 当一个节点被选…

Leetcode 最后一个单词的长度

给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1&#xff1a; 输入&#xff1a;s “Hello World” 输出&#xff1a;5 解释&a…

.netcore grpc截止时间和取消详解

一、截止时间概述 截止时间功能让 gRPC 客户端可以指定等待调用完成的时间。 超过截止时间时&#xff0c;将取消调用。 设定一个截止时间非常重要&#xff0c;因为它将提供调用可运行的最长时间。它能阻止异常运行的服务持续运行并耗尽服务器资源。截止时间对于构建可靠应用非…

【Git】(六)子模块跟随主仓库切换分支

场景 主仓库&#xff1a;TestGit 子模块&#xff1a;SubModule 分支v1.0 .gitmodules文件 [submodule "Library/SubModule"]path Library/SubModuleurl gitgitee.com:sunriver2000/SubModule.gitbranch 1.0.0.0 分支v2.0 .gitmodules文件 [submodule "Li…