java使用bouncycastle加解密

2023-11-07 00:28

本文主要是介绍java使用bouncycastle加解密,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

jdk默认带了一些常见的加解密方式,当我们常见的加解密不能满足时,就需要用到一些第三方的库了,bouncycastle就是其中一种。

但是bouncycastle文档比较少。简单介绍一下写法

1.导入依赖

   <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.69</version></dependency>

2.写代码

常见的有两种方式,一种使用BouncyCastleProvider,另一种使用BlockCipherEngine

BouncyCastleProvider使用方式跟原生jdk类似,多数getInstance的地方指定一下provider就行

BouncyCastleProvider方式DES加解密代码如下

package com.vvvtimes.demo.util.endecrypt;import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;@Slf4j
public class BcDesUtil {private static final BouncyCastleProvider provider;//BouncyCastle与JDK加解密类区别//KeyFactory.getInstance("RSA"); +provider-->KeyFactory.getInstance("RSA", provider)//Cipher.getInstance("RSA");  +provider-->Cipher.getInstance("RSA", provider)//Signature.getInstance("SHA1withRSA"); +provider-->Signature.getInstance("SHA1withRSA", provider);//KeyGenerator.getInstance("DES") ; +provider-->KeyGenerator.getInstance("DES", provider); 或者KeyGenerator.getInstance("DES","BC")/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "12345678";/** 生成key*/public byte[] generateKey() {KeyGenerator keyGenerator = null;try {keyGenerator = KeyGenerator.getInstance("DES",provider);keyGenerator.init(56);SecretKey secretKey = keyGenerator.generateKey();byte[] encoded = secretKey.getEncoded();return encoded;} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}/*** 生成key** @param password 密钥字符串* @return 密钥对象* @throws Exception*/private static Key convertKey(byte[] password) throws Exception {DESKeySpec dks = new DESKeySpec(password);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES",provider);return keyFactory.generateSecret(dks);}/*** DES加密*/public static byte[] encrypt(byte[] data, byte[] password) {if (password == null || password.length < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = convertKey(password);Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding",provider);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes("utf-8"));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] bytes = cipher.doFinal(data);return bytes;} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密解密字符串*/public static byte[] decrypt(byte[] data, byte[] password) {if (password == null || password.length < 8) {throw new RuntimeException("加密失败,key不能小于8位");}if (data == null)return null;try {Key secretKey = convertKey(password);Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding",provider);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes("utf-8"));cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);byte[] bytes = cipher.doFinal(data);return bytes;} catch (Exception e) {e.printStackTrace();return data;}}/*** byte数组转十六进制** @param bytes* @return*/public static String byte2HexString(byte[] bytes) {StringBuilder hex = new StringBuilder();if (bytes != null) {for (Byte b : bytes) {hex.append(String.format("%02X", b.intValue() & 0xFF));}}return hex.toString();}//测试public static void main(String[] args) throws Exception {String source = "admin测试信息1234!@#$%^&*()_+";System.out.println("原  文: " + source);String password = "lw112190@2023";byte[] encryptDataBytes = encrypt(source.getBytes("utf-8"), password.getBytes("utf-8"));String encryptData = byte2HexString(encryptDataBytes);System.out.println("加密后: " + encryptData);byte[] decryptDataBytes = decrypt(encryptDataBytes, password.getBytes("utf-8"));String decryptData = new String(decryptDataBytes, "utf-8");;System.out.println("解密后: " + decryptData);}static {provider = new BouncyCastleProvider();}
}

BlockCipherEngine方式的DES加解密代码如下

package com.vvvtimes.demo.util.endecrypt;import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.DESEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;public class BcDesEngineUtil {private final static BlockCipher engine;private static final BouncyCastleProvider provider;/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "12345678";/*** 生成key** @param password 密钥字符串* @return 密钥对象* @throws Exception*/private static byte[] convertKeyEncoded(byte[] password) {byte[] result = null;try {DESKeySpec dks  = new DESKeySpec(password);SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES",provider);SecretKey secretKey = keyFactory.generateSecret(dks);return secretKey.getEncoded();} catch (InvalidKeyException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (InvalidKeySpecException e) {e.printStackTrace();}return result;}private static byte[] encrypt( byte[] ptBytes,byte[] key) throws InvalidCipherTextException, UnsupportedEncodingException {BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine), new PKCS7Padding());cipher.init(true, new ParametersWithIV(new DESParameters(key), IV_PARAMETER.getBytes("utf-8")));byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)];int tam = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0);cipher.doFinal(rv, tam);return rv;}private static byte[] decrypt( byte[] cipherText,byte[] key) throws InvalidCipherTextException, UnsupportedEncodingException {BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine), new PKCS7Padding());cipher.init(false, new ParametersWithIV(new DESParameters( key),IV_PARAMETER.getBytes("utf-8")));byte[] rv = new byte[cipher.getOutputSize(cipherText.length)];int tam = cipher.processBytes(cipherText, 0, cipherText.length, rv, 0);cipher.doFinal(rv, tam);return rv;}/*** byte数组转十六进制** @param bytes* @return*/public static String byte2HexString(byte[] bytes) {StringBuilder hex = new StringBuilder();if (bytes != null) {for (Byte b : bytes) {hex.append(String.format("%02X", b.intValue() & 0xFF));}}return hex.toString();}//测试public static void main(String[] args) throws Exception {String source = "admin测试信息1234!@#$%^&*()_+";System.out.println("原  文: " + source);String password = "lw112190@2023";//String password ="geffzhan";//String password ="lw112190";byte[] keyEncoded = convertKeyEncoded(password.getBytes("utf-8"));byte[] encryptDataBytes = encrypt(source.getBytes("utf-8"), keyEncoded);String encryptData = byte2HexString(encryptDataBytes);System.out.println("加密后: " + encryptData);byte[] decryptDataBytes = decrypt(encryptDataBytes, keyEncoded);String decryptData = new String(decryptDataBytes, "utf-8");;System.out.println("解密后: " + decryptData);/**原  文: admin测试信息1234!@#$%^&*()_+加密后: 1D5C21B694A9085A69BE7EA37C197D1632239545298613B944C3AC272750A519F66FB43EFEC55C89解密后: admin测试信息1234!@#$%^&*()_+*/}static {engine = new DESEngine();provider = new BouncyCastleProvider();}}

3.其他示例

AES加解密

package com.vvvtimes.demo.util.endecrypt;import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidParameterSpecException;@Slf4j
public class BcAesUtil {private static final BouncyCastleProvider provider;/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "1234567890123456";/*** AES加密*/public static byte[] encrypt(byte[] data, byte[] password, byte[] iv) {if (data == null)return null;try {Key secretKey = new SecretKeySpec(password,"AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding",provider);AlgorithmParameters generateIV = generateIV(iv);cipher.init(Cipher.ENCRYPT_MODE, secretKey, generateIV);byte[] bytes = cipher.doFinal(data);return bytes;} catch (Exception e) {e.printStackTrace();return data;}}/*** AES解密解密字符串*/public static byte[] decrypt(byte[] data, byte[] password, byte[] iv) {if (data == null)return null;try {Key secretKey = new SecretKeySpec(password,"AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding",provider);AlgorithmParameters generateIV = generateIV(iv);cipher.init(Cipher.DECRYPT_MODE, secretKey, generateIV);byte[] bytes = cipher.doFinal(data);return bytes;} catch (Exception e) {e.printStackTrace();return data;}}public static AlgorithmParameters generateIV(byte[] iv){AlgorithmParameters params = null;try {params = AlgorithmParameters.getInstance("AES");params.init(new IvParameterSpec(iv));} catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {e.printStackTrace();}return params;}/*** byte数组转十六进制** @param bytes* @return*/public static String byte2HexString(byte[] bytes) {StringBuilder hex = new StringBuilder();if (bytes != null) {for (Byte b : bytes) {hex.append(String.format("%02X", b.intValue() & 0xFF));}}return hex.toString();}//测试public static void main(String[] args) throws Exception {String source = "admin测试信息1234!@#$%^&*()_+";System.out.println("原  文: " + source);String password = "passwordpassword";byte[] encryptDataBytes = encrypt(source.getBytes("utf-8"), password.getBytes("utf-8"),IV_PARAMETER.getBytes("utf-8"));String encryptData = byte2HexString(encryptDataBytes);System.out.println("加密后: " + encryptData);byte[] decryptDataBytes = decrypt(encryptDataBytes, password.getBytes("utf-8"),IV_PARAMETER.getBytes("utf-8"));String decryptData = new String(decryptDataBytes, "utf-8");System.out.println("解密后: " + decryptData);}static {provider = new BouncyCastleProvider();}
}

RSA私钥解密 签名

package com.vvvtimes.demo.util.endecrypt;import cn.hutool.core.codec.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;public class BcRsaUtil {private static final BouncyCastleProvider provider;private static PrivateKey getPrivateKey(String pkcs8Key) {byte[] pkcs8Keybytes = Base64.decode(pkcs8Key.getBytes(Charset.forName("UTF-8")));final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(pkcs8Keybytes);try {return KeyFactory.getInstance("RSA", provider).generatePrivate(pkcs8EncodedKeySpec);} catch (Exception ex) {ex.printStackTrace();return null;}}/*** RSA私钥解密** @param inputByte 待解密字节数组* @param pkcs8Key  私钥* @return 明文*/public static byte[] decrypt(byte[] inputByte, String pkcs8Key) {byte[] outputeByte = null;try {PrivateKey privateKey = getPrivateKey(pkcs8Key);//RSA解密Cipher cipher = Cipher.getInstance("RSA", provider);cipher.init(Cipher.DECRYPT_MODE, privateKey);outputeByte = cipher.doFinal(inputByte);} catch (NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException e) {e.printStackTrace();}return outputeByte;}public static byte[] sign(final byte[] array, String pkcs8Key) {try {PrivateKey privateKey = getPrivateKey(pkcs8Key);final Signature instance = Signature.getInstance("SHA1withRSA", provider);instance.initSign(privateKey);instance.update(array);return instance.sign();} catch (GeneralSecurityException ex) {throw new RuntimeException("License Server installation error 0000000F2", ex);}}static {provider = new BouncyCastleProvider();}
}

实际上bouncycastle还支持部分国密算法,这一部分不用自己写实现了。

这篇关于java使用bouncycastle加解密的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/360008

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do