深入理解非对称加密:用Java实现RSA加解密

server/2025/1/9 6:49:41/

目录

一、非对称加密算法概述

二、Java 中实现非对称加密


非对称加密(Asymmetric Encryption)是一种加密方式,其中使用一对密钥:公钥(Public Key)和私钥(Private Key)。这种加密算法的核心特征是:公钥用来加密数据,而私钥用来解密数据。这与对称加密算法(Symmetric Encryption)不同,对称加密只使用一个密钥来加解密数据。
在现代安全通信中,非对称加密广泛应用于数据保护、身份验证、数字签名、SSL/TLS协议等场景。非对称加密算法中最常见的算法是 RSA(Rivest-Shamir-Adleman)算法。
本文将通过 Java 实现一个简单的非对称加密算法示例,演示公钥加密和私钥解密的基本过程。

一、非对称加密算法概述

1.非对称加密的核心是密钥对的生成:

(1)公钥:可以公开,用于加密数据,任何人都可以使用。
(2)私钥:保密,用于解密数据,只有密钥的持有者才能使用。

二、Java 中实现非对称加密

在 Java 中,非对称加密可以通过 java.security 包中的 KeyPairGenerator、Cipher、KeyFactory 等类来实现。以下是实现过程的详细步骤:

(1)公钥和私钥的生成

在使用 RSA 算法时,首先需要生成一对公钥和私钥。Java 提供了 KeyPairGenerator 类来生成密钥对。

java">import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.NoSuchAlgorithmException;public class KeyPairExample {public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {// 创建一个 RSA 密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);  // 设置密钥的大小为 2048 位return keyPairGenerator.generateKeyPair();  // 生成密钥对}public static void main(String[] args) throws NoSuchAlgorithmException {// 生成公钥和私钥KeyPair keyPair = generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 输出公钥和私钥System.out.println("公钥: " + publicKey);System.out.println("私钥: " + privateKey);}
}

上述代码中,KeyPairGenerator.getInstance("RSA") 用来初始化一个 RSA 算法的密钥对生成器,然后通过 keyPairGenerator.generateKeyPair() 生成公钥和私钥。

(2)公钥加密

公钥用来加密数据,任何人都可以使用公钥来加密数据,但只有对应的私钥持有者才能解密。

java">import javax.crypto.Cipher;
import java.security.PublicKey;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.util.Base64;public class EncryptionExample {public static String encryptWithPublicKey(String data, PublicKey publicKey)throws Exception {Cipher cipher = Cipher.getInstance("RSA");  // 创建一个 RSA 加密器cipher.init(Cipher.ENCRYPT_MODE, publicKey);  // 初始化为加密模式byte[] encryptedData = cipher.doFinal(data.getBytes());  // 执行加密操作return Base64.getEncoder().encodeToString(encryptedData);  // 返回 Base64 编码的加密结果}public static void main(String[] args) throws Exception {String data = "Hello, this is a secret message!";KeyPair keyPair = KeyPairExample.generateKeyPair();  // 生成密钥对PublicKey publicKey = keyPair.getPublic();// 使用公钥加密数据String encryptedData = encryptWithPublicKey(data, publicKey);System.out.println("加密后的数据: " + encryptedData);}
}

在此代码中,Cipher.getInstance("RSA") 创建一个 RSA 加密算法的实例,cipher.init(Cipher.ENCRYPT_MODE, publicKey) 将加密器初始化为加密模式,并指定公钥。通过 cipher.doFinal() 方法对数据进行加密,返回加密后的字节数组,最后使用 Base64 编码输出。

(3)私钥解密

私钥用来解密数据,只有私钥持有者才能解密通过公钥加密的数据。

java">import javax.crypto.Cipher;
import java.security.PrivateKey;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.util.Base64;public class DecryptionExample {public static String decryptWithPrivateKey(String encryptedData, PrivateKey privateKey)throws Exception {Cipher cipher = Cipher.getInstance("RSA");  // 创建一个 RSA 解密器cipher.init(Cipher.DECRYPT_MODE, privateKey);  // 初始化为解密模式byte[] decodedData = Base64.getDecoder().decode(encryptedData);  // Base64 解码byte[] decryptedData = cipher.doFinal(decodedData);  // 执行解密操作return new String(decryptedData);  // 返回解密后的数据}public static void main(String[] args) throws Exception {String data = "Hello, this is a secret message!";KeyPair keyPair = KeyPairExample.generateKeyPair();  // 生成密钥对PrivateKey privateKey = keyPair.getPrivate();// 假设已通过公钥加密过的数据String encryptedData = EncryptionExample.encryptWithPublicKey(data, keyPair.getPublic());// 使用私钥解密数据String decryptedData = decryptWithPrivateKey(encryptedData, privateKey);System.out.println("解密后的数据: " + decryptedData);}
}

在解密过程中,Base64.getDecoder().decode() 先将加密的字符串进行解码,cipher.init(Cipher.DECRYPT_MODE, privateKey) 初始化解密模式,并使用私钥进行解密,最后输出解密后的结果。

(4)结果展示

当运行上述代码时,会得到类似以下的输出:

java">公钥: java.security.interfaces.RSAPublicKey@15db9742
私钥: java.security.interfaces.RSAPrivateKey@6d06d69c
加密后的数据: MHwwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
解密后的数据: Hello, this is a secret message!

三、总结

非对称加密算法通过公钥和私钥的配对实现数据的加密与解密,确保了数据的安全性。Java 提供了丰富的加密支持,可以方便地实现非对称加密。在实际应用中,非对称加密主要用于数据传输的加密和数字签名等场景。

(1)公钥加密:任何人可以使用公钥加密数据,但只能由私钥持有者解密。
(2)私钥解密:通过私钥解密公钥加密的数据,保证数据的机密性。

RSA 是最常见的非对称加密算法,它的安全性基于大数分解的困难性。在实际应用中,常常结合对称加密算法(如 AES)来提高加解密性能,利用非对称加密算法传输对称密钥,从而实现安全和高效的数据加密。


http://www.ppmy.cn/server/156545.html

相关文章

OpenGL —— 流媒体播放器 - ffmpeg解码rtsp流,opengl渲染yuv视频(附源码,glfw+glad)

效果 说明 FFMpeg和OpenGL作为两大技术巨头,分别在视频解码和图形渲染领域发挥着举足轻重的作用。本文将综合两者实战视频播放器,大概技术流程为:ffmpeg拉取rtsp协议视频流,并经过解码、尺寸格式转换为yuv420p后,使用opengl逐帧循环渲染该yuv实时视频。 核心源码 vertexSh…

Uniapp Android 本地离线打包(详细流程)

一、简介 App 离线 SDK 暂时不支持 Kotlin,未来不清楚。 uniapp 提供了 云打包 与 本地打包 两种方案,云打包 需要排队且还有次数限制,本地打包 则就没有这些限制,而且会 本地打包 对开发 原生插件 有很大的帮助。 细节&#x…

(安卓无线调试)ADB 无法连接及 Scrcpy 问题排查指南

问题描述 在使用 ADB 和 Scrcpy 时遇到以下问题&#xff1a; 无法连接到 ADB 服务。 即使连接成功&#xff0c;Scrcpy 显示以下错误&#xff1a; INFO: scrcpy 1.10 <https://github.com/Genymobile/scrcpy> D:\.....\scrcpy\scrcpy-server.jar: 1 file pushed. 0.2 …

行为模式4.观察者模式------消息推送

行为型模式 模板方法模式&#xff08;Template Method Pattern&#xff09;命令模式&#xff08;Command Pattern&#xff09;迭代器模式&#xff08;Iterator Pattern&#xff09;观察者模式&#xff08;Observer Pattern&#xff09;中介者模式&#xff08;Mediator Pattern…

基于云架构Web端的工业MES系统:赋能制造业数字化变革

基于云架构Web端的工业MES系统:赋能制造业数字化变革 在当今数字化浪潮席卷全球的背景下,制造业作为国家经济发展的重要支柱产业,正面临着前所未有的机遇与挑战。市场需求的快速变化、客户个性化定制要求的日益提高以及全球竞争的愈发激烈,都促使制造企业必须寻求更加高效、智…

在K8S中,Pod请求另一个Pod偶尔出现超时或延迟,如何排查?

在Kubernetes中&#xff0c;当Pod请求另一个Pod时偶尔出现超时或延迟&#xff0c;可能是由于多种原因造成的。以下是一些建立的排查步骤&#xff1a; 1. 检查网络配置和插件&#xff1a; 确认你的kubernetes集群使用了合适的网络插件&#xff08;如Calico、Flannel等&#xf…

四种线程池的创建及任务提交

1. 线程池概述 1.1 线程池的定义 线程池是管理和控制线程使用的一种手段。它通过提前创建一定数量的线程&#xff0c;并将任务提交给这些线程执行&#xff0c;来实现资源的合理分配和任务的高效处理。 关键点&#xff1a; 线程复用&#xff1a;线程池在任务执行完毕后&#…

ELK日志平台搭建 (最新版)

一、安装 JDK 1. 下载 JDK 21 RPM 包 wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.rpm2. 安装 JDK 21,使用 rpm 命令安装下载的 RPM 包&#xff1a; sudo rpm -ivh jdk-21_linux-x64_bin.rpm3. 配置环境变量 编辑 /etc/profile 文件以配置 JAVA_HO…