【异常】java11提示: Cannot find any provider supporting RSA/ECB/PKCS1Padding的问题

news2025/2/6 0:54:12

一、背景

项目中需要对敏感字段进行加密,但是加密方法中涉及到比较复杂的加密算法,这些算法都需要一个Provider,主要是用于初始化算法的。
以下是遇到的具体问题

二、报错截图

在这里插入图片描述

java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/PKCS1Padding

三、报错原因

原因是我们运行的jre不支持,对方使用的是JDK8,而我们的是JDK11
不仅出现了上面的问题,而且,对于对方已经加密的字符串,我们无法正常解析。
那这两者有什么区别呢?估计是模块化的区别。
见文章
Java9的新特性模块化(Module)

四、问题解决

4.1 Step1、引入POM文件

 		 <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
         <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk14</artifactId>
            <version>1.46</version>
            <scope>compile</scope>
        </dependency>

4.2 Step2、Security.addProvider

加入BouncyCastleProvider,该类属于org.bouncycastle.jce.provider包

调用的方法面前加入这段方法即可,用于初始化算法

//初始化
Security.addProvider(new BouncyCastleProvider());

4.2.1 Security.addProvider()方法的具体详情如下:

包路径:java.security.Security (提供安全框架的类和接口。)
类名称:Security
方法名:addProvider

五、 样例代码

5.1 案例代码:SymAlgoUtils.messageCrypt

public static String getActualVin(String vinCryptoCipher) {
        byte[] vinCryptoKey = new byte[0];
        String vinCryptoPlainHexStr = null;
        try {
            Security.addProvider(new BouncyCastleProvider());
            vinCryptoKey = KDFUtils.genVinCryptoKey();
            vinCryptoPlainHexStr = SymAlgoUtils.messageCrypt(Cipher.DECRYPT_MODE, vinCryptoKey, BasicConvertUtils.hexString2byteArray(vinCryptoCipher));
        } catch (Exception e) {
            log.error("getActualVin fail! decrypt error ,vinCryptoCipher= 【{}】, vinCryptoKey =【{}】, e=【{}】",
                    vinCryptoCipher, vinCryptoKey, e.getMessage());
            return vinCryptoCipher;
        }
        if (StrUtil.isBlank(vinCryptoPlainHexStr)) {
            log.error("getActualVin fail! vinCryptoPlainHexStr = 【{}】 is blank", vinCryptoCipher);
            return vinCryptoCipher;
        }
        // 解密后可见的明文VIN码
        return BasicConvertUtils.hexStr2Str(vinCryptoPlainHexStr);
    }

5.2 案例代码:AES加密工具类

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Arrays;

//AES加密工具类
@Component
public class AesUtil {
    /**
     * AES128 算法
     * CBC 模式
     * PKCS7Padding 填充模式
     * CBC模式需要添加一个参数iv
     * 介于java 不支持PKCS7Padding,只支持PKCS5Padding 
     * 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
     */
    private Key key;
    private Cipher cipher;
    String aesKey = "1111bat1977";
    byte[] iv = "7773066605060999".getBytes();
    byte[] keyBytes = aesKey.getBytes();

    public void init(byte[] keyBytes) {
        // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, CipherType.AES_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(CipherType.AES_CBC_PKC7PADDING, "BC");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public String encrypt(String content) {
        return Base64.encode(encrypt(content.getBytes(), keyBytes));
    }
    public String encrypt(String content, String keyBytes) {
        return Base64.encode(encrypt(content.getBytes(), keyBytes.getBytes()));
    }
    public String encryptByHex(String content, String keyBytes) {
        return HexUtil.encodeHexStr(encrypt(content.getBytes(), keyBytes.getBytes()));
    }
    public String encryptByHex(String content) {
        return HexUtil.encodeHexStr(encrypt(content.getBytes(), keyBytes));
    }

    /**
     * 加密方法
     * @param content  要加密的字符串
     * @param keyBytes 加密密钥
     * @return
     */
    public byte[] encrypt(byte[] content, byte[] keyBytes) {
        byte[] encryptedText = null;
        keyBytes = new String(keyBytes).getBytes();
        init(keyBytes);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(content);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return encryptedText;
    }
    public String decrypt(String encryptedData) {
        return new String(decrypt(Base64.decode(encryptedData), keyBytes));
    }
    public String decrypt(String encryptedData, String keyData) {
        return new String(decrypt(Base64.decode(encryptedData), keyData.getBytes()));
    }
    public String decryptByHex(String encryptedData, String keyData) {
        return new String(decrypt(HexUtil.decodeHex(encryptedData), keyData.getBytes()));
    }
    public String decryptByHex(String encryptedData) {
        return new String(decrypt(HexUtil.decodeHex(encryptedData), keyBytes));
    }
    /**
     * 解密方法
     * @param encryptedData 要解密的字符串
     * @param keyBytes      解密密钥
     */
    public byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
        byte[] encryptedText = null;
        init(keyBytes);
        try {
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
            encryptedText = cipher.doFinal(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedText;
    }

    public static void main(String[] args) {
        AesUtil aes = new AesUtil();
        //加密字符串
        String content = "{\"userName\":\"12\",\"userPhone\":\"123\"}";
        System.out.println("加密前的:" + content);
        // 加密方法
        String encStr = aes.encryptByHex(content);
        System.out.println("加密后的内容:" + encStr);
        // 解密方法
        String decStr = aes.decryptByHex(encStr);
        System.out.println("解密后的内容:" + decStr);
    }
}
加密前的:{"userName":"12","userPhone":"123"}
加密后的内容:989f16833c907f8168a6dc81424f136726a2fdf587f83360d8e24ef4506ffbfd69f0a7453a97dcc609acb3d312b4bf77
解密后的内容:{"userName":"12","userPhone":"123"}

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

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

相关文章

【软件测试】软件测试模型

1. V模型 需求分析—计划—设计—编码—测试 ● 概要设计&#xff1a;设计整体架构&#xff0c;框架 ● 详细设计&#xff1a;模块和模块之间的详细设计 ● 集成测试&#xff0c;单元测试&#xff1a;通常由开发人员进行 特点&#xff1a; 明确标注了测试的多类型明确标注了测…

Introduction to Multi-Armed Bandits——01 Scope and Motivation

Introduction to Multi-Armed Bandits——01 Scope and Motivation 参考资料 Slivkins A. Introduction to multi-armed bandits[J]. Foundations and Trends in Machine Learning, 2019, 12(1-2): 1-286.项目地址 https://github.com/yijunquan-afk/bandit-learning Bandit…

LeetCode622.设计循环队列

设计循环队列1.题目描述2.思路3.代码实现以及分析3.1 创建结构体3.2创建一个具体的循环队列3.3判断是否为空 和 判断是否为满4. 进队列 和 出队列5.取队首和队尾元素6.释放空间7.总结1.题目描述 设计循环队列 2.思路 环形队列的抽象图 我们这里使用数组模拟实现循环队列&…

TransactionTemplate自动注入,只看这一篇文章就够了

标准的springboot接入mybatis步骤 1.引入了对应的依赖包 2.应用的properties下增加相应配置 3.根据配置进行自动装配 一般我们会配置这些信息&#xff0c;主要包括三类 1.数据库的连接信息 2.指定的数据源类型 3.mybatis的配置信息 配完以后&#xff0c;当你启动SpringBoot的主…

你是真的“C”——详解C语言数组模块知识

详解C语言数组模块知识&#x1f60e;前言&#x1f64c;一维数组的创建和初始化&#x1f64c;1.1 数组的创建&#x1f49e;1.2 数组的初始化&#x1f49e;1.3 一维数组的使用&#x1f49e;1.4 一维数组在内存中的存储&#x1f49e;二维数组的创建和初始化&#x1f64c;1.1 二维数…

【Python百日进阶-数据分析】Day225 - plotly的Ohlc图go.Ohlc()

文章目录一、语法二、参数三、返回值四、实例4.1 简单的OHLC图4.2 隐藏滑块的OHLC图4.3 添加自定义文本和注释4.4 自定义OHLC颜色4.5 带日期时间对象的简单的OHLC图4.6 自定义悬浮文本4.7 Dash中的应用一、语法 ohlc&#xff08;Open-High-Low-Close 的缩写&#xff09;是一种…

【C++逆向】虚表(Virtual table)逆向 | 安卓so虚函数逆向

什么是多态 定义一个虚基类ISpeaker class ISpeaker{ protected:size_t b; public:ISpeaker( size_t _v ): b(_v) {}virtual void speak() 0; };有两个子类&#xff0c;都实现了虚函数speak()&#xff1a; class Dog : public ISpeaker { public:Dog(): ISpeaker(0){}//vir…

1581_AURIX_TC275_SMU故障处理梳理

全部学习汇总&#xff1a; GreyZhang/g_TC275: happy hacking for TC275! (github.com) 前面为了缓解自己的学习压力&#xff0c;一次学习笔记大概也就是看10页文档整理一下。这一次其实是看了几十页&#xff0c;但是里面过掉了一些信息&#xff0c;而且这部分内容不是很好拆分…

hive在IDEA中debug

一、hive在IDEA中debug 安装hadoop环境&#xff08;1和2替换顺序也可以&#xff09; 注&#xff1a;hadoop环境不需要从源码编译 https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html 按照官网教程编译源码 https://cwiki.apach…

软件工程专业课实验报告

一、结构化分析方法1.1需求描述教务管理子系统的需求描述&#xff1a;教务管理是一项需求周密计划、严谨安排的工作&#xff0c;要依据教师、学生信息进行合理安排。开学阶段&#xff0c;需要教师提交开课申请进行开课&#xff0c;学生根据老师的开课信息&#xff0c;选择课程&…

uview 使用遇到的问题。

uviewuniappvue&#xff0c;uView是uni-app生态专用的UI框架。 1. 注意uview版本&#xff0c;uview 2.0与uview1.0 官方提示&#xff1a;uView2.0是继1.0以来的一次重大更新&#xff0c;2.0已全面兼容nvue。 因此在接手项目的时候首先得看清楚&#xff0c;之前开发的是uview…

【自学Python】Python获取字符串长度

Python获取字符串长度 Python获取字符串长度教程 在 Python 中要想获取 字符串 长度可以使用 len() 函数。 Python len()函数详解 定义 我们将要获取的字符串的长度&#xff0c;传进 len() 函数&#xff0c;即可实现获取字符串的长度。 语法 len(string)参数 参数描述s…

【7】K8s_Ingress | Service的统一网关入口

目录 1、Ingress简介 2、安装ingress 【1】制作ingress.yaml文件并执行 【2】测试&#xff0c;创建一个test.yaml文件并执行 【3】设置域名访问&#xff0c;用yaml文件 【4】路径重写 【5】流量限制 1、Ingress简介 Ingress: Service的统一网关入口是k8s中的一个api对象&…

时序数据库TDengine基本概念和建模思路

目录 一 、 时序数据库基本概念 采集量 标签 数据采集点 表 超级表 子表 库 二、 TDengine数据库建模策略 建表模式建表情形 行列数据库存储的区别&#xff1a; 接触的传统业务的数据模式都是行存储&#xff0c;我们会把不同类型的对象创建不同的表进行存储他们各自的属…

机器学习公式推导与代码实现-无监督学习模型

聚类分析与k均值聚类算法 督学习算法。在给定样本的情况下,聚类分析通过度量特征相似度或者距离,将样本自动划分为若干类别。 距离度量和相似度度量方式 距离度量和相似度度量是聚类分析的核心概念,大多数聚类算法建立在距离度量之上。常用的距离度量方式包括闵氏距离和马…

linux系统中使用QT来实现数据库的调用方法

大家好&#xff0c;今天主要和大家分享一下&#xff0c;如何使用QT中数据库的使用方法。 目录 第一&#xff1a;数据库基本简介 第二&#xff1a;数据库表格基本操作 第三&#xff1a;数据库最终效果 第一&#xff1a;数据库基本简介 数据库是按照数据结构来组织&#xff0c;…

视频目标检测与轨迹跟踪代码案例

前言通过阅读相关文献及测试&#xff0c;找到了一种基于多模板匹配的改进方法&#xff0c;可以对遥感视频卫星中的移动目标进行探测&#xff0c;并绘制其轨迹。根据实验结果发现&#xff0c;可以比较有效的对运动目标进行跟踪。一、原理核心思想比较简单。即通过不同旋转角度的…

AQS之ReentrantLock详解

非公平锁加锁过程一般我们在使用ReentrantLock的时候&#xff0c;代码如下&#xff1a;Test public void test(){ReentrantLock lock new ReentrantLock();lock.lock();try{//编写业务逻辑}catch (Exception e){lock.unlock();} }当我们在用ReentrantLock独占锁的时候&#xf…

current并发包

并发包 current并发包、在JDK1.5之前Java并没有提供线程安全的一些工具类去操作多线程&#xff0c;需要开发人员自行编写实现线程安全&#xff0c;但仍然无法完全避免低性能、死锁、资源管理等问题。在JDK1.5时新增了java.util.current并发包&#xff0c;其中提供了许多供我们…

【自学Python】Python截取字符串

Python截取字符串 Python截取字符串教程 在 Python 中&#xff0c;我们需要截取 字符串&#xff0c;不需要使用特定的 函数&#xff0c;只需要使用下标索引加上切片的形式&#xff0c;就可以实现字符串的截取。 Python字符 Python 中没有单个字符的概念&#xff0c;单个字符…