Java实现OpenSSL加解密

2024-08-24 14:44
文章标签 java 实现 openssl 加解密

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

在Java中实现使用OpenSSL进行密钥的加密和解密,可以通过Java调用OpenSSL命令来完成。

调用OpenSSL

1. 使用OpenSSL进行密钥加密

import java.io.BufferedReader;
import java.io.InputStreamReader;public class OpenSSLUtil {/*** 使用OpenSSL加密密钥** @param secretKey 要加密的密钥* @param passphrase 用于加密的密码短语* @return 加密后的密钥字符串*/public static String encryptSecretKey(String secretKey, String passphrase) {try {// 构建OpenSSL加密命令String command = String.format("echo -n %s | openssl enc -aes-256-cbc -a -pass pass:%s", secretKey, passphrase);Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", command});// 读取加密后的输出BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));StringBuilder output = new StringBuilder();String line;while ((line = reader.readLine()) != null) {output.append(line);}process.waitFor();return output.toString();} catch (Exception e) {e.printStackTrace();throw new RuntimeException("Failed to encrypt secret key with OpenSSL");}}/*** 使用OpenSSL解密密钥** @param encryptedKey 加密后的密钥字符串* @param passphrase 用于解密的密码短语* @return 解密后的密钥字符串*/public static String decryptSecretKey(String encryptedKey, String passphrase) {try {// 构建OpenSSL解密命令String command = String.format("echo %s | openssl enc -aes-256-cbc -d -a -pass pass:%s", encryptedKey, passphrase);Process process = Runtime.getRuntime().exec(new String[]{"bash", "-c", command});// 读取解密后的输出BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));StringBuilder output = new StringBuilder();String line;while ((line = reader.readLine()) != null) {output.append(line);}process.waitFor();return output.toString();} catch (Exception e) {e.printStackTrace();throw new RuntimeException("Failed to decrypt secret key with OpenSSL");}}public static void main(String[] args) {// 加密和解密密钥String secretKey = "123456";String password = "admin";// 加密密钥String encryptedKey = encryptSecretKey(secretKey, password);System.out.println("Encrypted Key: " + encryptedKey);// 解密密钥String decryptedKey = decryptSecretKey(encryptedKey, password);System.out.println("Decrypted Key: " + decryptedKey);}
}
  • 加密和解密输出结果
# Encrypted Key: U2FsdGVkX1+Nm96WU2sh6KBKIsNIwD3grcJ2L9Qgkl0=
# Decrypted Key: 123456

2. 说明

  • 加密密钥encryptSecretKey方法使用OpenSSL通过AES-256-CBC算法和指定的password对给定的secretKey进行加密。加密后的密钥以Base64编码的形式返回。

  • 解密密钥decryptSecretKey方法使用相同的password对加密的密钥进行解密。返回的解密密钥应与原始密钥相同。

3. 注意

  • 依赖的环境:确保在执行代码的机器上已经安装了OpenSSL,并且可以通过命令行调用。

非调用OpenSSL

使用Java的内置加密库来实现相同的功能。Java提供了javax.crypto包来进行加密和解密操作,可以实现类似于OpenSSL的AES-256-CBC加密算法。

1. AES-256-CBC 加密和解密实现

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;public class AESUtil {// 使用AES-256-CBC加密public static String encrypt(String plainText, String secretKey, String initVector) {try {IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));SecretKeySpec skeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);byte[] encrypted = cipher.doFinal(plainText.getBytes());return Base64.getEncoder().encodeToString(encrypted);} catch (Exception ex) {throw new RuntimeException("Error while encrypting: " + ex.toString());}}// 使用AES-256-CBC解密public static String decrypt(String encryptedText, String secretKey, String initVector) {try {IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));SecretKeySpec skeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedText));return new String(original);} catch (Exception ex) {throw new RuntimeException("Error while decrypting: " + ex.toString());}}public static void main(String[] args) {// 加密和解密String secretKey = "12345678901234567890123456789012"; // 32字节的密钥String initVector = "RandomInitVector"; // 16字节的初始化向量String password = "123456";System.out.println("Original Text: " + 123456);// 加密String encryptedText = encrypt(originalText, secretKey, initVector);System.out.println("Encrypted Text: " + 123456);// 解密String decryptedText = decrypt(encryptedText, secretKey, initVector);System.out.println("Decrypted Text: " + decryptedText);}
}

2. 说明

  • 密钥 (SecretKey):使用32字节(256位)的密钥进行AES-256加密。确保密钥长度为32字节。
  • 初始化向量 (IV):使用16字节的初始化向量(IV),用于确保相同的明文在每次加密时产生不同的密文。
  • 加密方法encrypt方法使用AES-256-CBC模式进行加密,并返回Base64编码后的加密字符串。
  • 解密方法decrypt方法将Base64编码的密文解码并使用AES-256-CBC模式进行解密,返回原始明文。

3. 结果

# Original Text: 123456
# Encrypted Text: PcYQ/IF5BlE/yCLVwbojOg==
# Decrypted Text: 123456

4. 注意

  • 密钥管理:确保加密密钥的安全管理,不应将其硬编码到源代码中。在实际应用中,密钥和IV应从安全的配置或密钥管理系统中获取。
  • 初始化向量 (IV):对于每次加密操作,应使用不同的IV以确保安全性。IV不需要保密,但应与密文一起存储或传输,以便解密时使用。

这篇关于Java实现OpenSSL加解密的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Python实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

PyQt6/PySide6中QTableView类的实现

《PyQt6/PySide6中QTableView类的实现》本文主要介绍了PyQt6/PySide6中QTableView类的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学... 目录1. 基本概念2. 创建 QTableView 实例3. QTableView 的常用属性和方法

PyQt6/PySide6中QTreeView类的实现

《PyQt6/PySide6中QTreeView类的实现》QTreeView是PyQt6或PySide6库中用于显示分层数据的控件,本文主要介绍了PyQt6/PySide6中QTreeView类的实现... 目录1. 基本概念2. 创建 QTreeView 实例3. QTreeView 的常用属性和方法属性

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型