Java:实现RSA加密与验证的方法详解

1 RSA简介

RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称为公钥和私钥。两者之间有数学相关,该加密算法的原理就是对一极大整数做因数分解的困难性来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)。

主要特点如下:

  • 非对称加密: RSA是一种非对称加密算法,意味着它使用不同的密钥进行加密和解密。公钥用于加密数据,只有拥有相应私钥的用户才能解密它。这种非对称性使得RSA在安全通信中非常有用,因为公钥可以公开分享,而私钥必须保密。
  • 数字签名和验证: RSA还可以用于数字签名和验证。发送方可以使用其私钥对消息进行签名,接收方可以使用发送方的公钥来验证签名。这确保了消息的完整性和来源认证。数字签名在网络安全、电子邮件认证和电子商务中广泛使用。
  • 密钥交换: RSA可用于安全地交换对称密钥。在两个通信方之间建立安全连接时,可以使用RSA加密传输对称密钥,然后使用该对称密钥进行快速的数据加密和解密。这提高了性能并确保了密钥的安全交换。
  • 安全通信: RSA可用于保护通信的机密性和完整性。通信双方可以使用对方的公钥来加密数据,以确保只有持有私钥的一方能够解密它。这在保护敏感信息传输时非常重要,例如,网上银行、电子商务和VPN连接。
  • 数字证书: RSA也与数字证书一起使用,以验证网站的身份和安全性。数字证书中包含了网站的公钥,通过验证证书的签名,用户可以确保他们正在与合法的网站通信,而不是受到中间人攻击。
  • 安全存储: RSA可以用于加密敏感数据,然后将其存储在不安全的环境中,只有持有私钥的用户才能解密和访问数据。这对于存储密码、加密钱包和数据库等敏感数据非常有用。

总的来说,RSA是一种强大且多用途的加密算法,广泛应用于网络通信、数据安全、数字签名、身份验证和加密存储等领域。然而,需要注意的是,RSA的性能较低,特别是对于长消息,因此在某些情况下,可能需要与对称加密算法结合使用,以提高性能。

2 使用场景举例

加密和签名都是为了安全性考虑,但略有不同。常有人问加密和签名是用私钥还是公钥?其实都是对加密和签名的作用有所混淆。简单的说,加密是为了防止信息被泄露,而签名是为了防止信息被篡改。这里举2个例子说明。

场景一:

战场上,B要给A传递一条消息,内容为某一指令。

RSA的加密过程如下:

  • A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
  • A传递自己的公钥给B,B用A的公钥对消息进行加密。
  • A接收到B加密的消息,利用A自己的私钥对消息进行解密。

在这个过程中,只有2次传递过程,第一次是A传递公钥给B,第二次是B传递加密消息给A,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行解密,防止了消息内容的泄露。

场景二:

A收到B发的消息后,需要进行回复“收到”。

RSA签名的过程如下:

  • A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
  • A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
  • B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。

在这个过程中,只有2次传递过程,第一次是A传递加签的消息和消息本身给B,第二次是B获取A的公钥,即使都被敌方截获,也没有危险性,因为只有A的私钥才能对消息进行签名,即使知道了消息内容,也无法伪造带签名的回复给B,防止了消息内容的篡改。

但是,综合两个场景你会发现,第一个场景虽然被截获的消息没有泄露,但是可以利用截获的公钥,将假指令进行加密,然后传递给A。第二个场景虽然截获的消息不能被篡改,但是消息的内容可以利用公钥验签来获得,并不能防止泄露。所以在实际应用中,要根据情况使用,也可以同时使用加密和签名,比如A和B都有一套自己的公钥和私钥,当A要给B发送消息时,先用B的公钥对消息加密,再对加密的消息使用A的私钥加签名,达到既不泄露也不被篡改,更能保证消息的安全性。

3 代码实现

3.1 生成公私钥

要实现加密和验证,首先你需要生成一对RSA密钥对,包括公钥和私钥。你可以使用Java的KeyPairGenerator类来生成密钥对。实现代码如下:

package com.example.demo;import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;public class GenerateRSAKeys {public static void main(String[] args) throws Exception {// 创建一个RSA密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");// 设置密钥长度,通常为2048位keyPairGenerator.initialize(2048);// 生成RSA密钥对KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();System.out.println("公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));System.out.println("私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));}
}

3.2 基础的公钥加密私钥解密

package com.example.demo;import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;public class RSAEncryptionDecryption {public static void main(String[] args) throws Exception {String originalText = "Hello, RSA encryption and decryption!";// 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApzRwXn03DL1Hf7rEuElyaY9UrDnB87VFoPkTj743bxkhrXmuFuuk3JkSDPBY6IGwbFwaVIHMsMiMEh4ZVq7m/dOYBlWnAzZnZk/uWxF1zUJ2C6xe92R97m/4ySOYypg9SI9sPscOyYY4rw/vGaos+uhsoyt26chFbU/BdtFzq7+843gjUzzHR/kpD61c/IeWiYoB6RFKoMgmzKlPXMGsmfrsQynUuCK+xuRj22Xf38XLjQXh+t5l1x3Q/MbixyPf0zWCrCxFDdvAy/BQwt7X5TEui//epGK+g3JC504EGcxGVkAZdwPCo9swqxQvTdVYLIR0QWPUCIFEmvaZRSvyNQIDAQAB";String privateKeyBase64 = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnNHBefTcMvUd/usS4SXJpj1SsOcHztUWg+ROPvjdvGSGtea4W66TcmRIM8FjogbBsXBpUgcywyIwSHhlWrub905gGVacDNmdmT+5bEXXNQnYLrF73ZH3ub/jJI5jKmD1Ij2w+xw7JhjivD+8Zqiz66GyjK3bpyEVtT8F20XOrv7zjeCNTPMdH+SkPrVz8h5aJigHpEUqgyCbMqU9cwayZ+uxDKdS4Ir7G5GPbZd/fxcuNBeH63mXXHdD8xuLHI9/TNYKsLEUN28DL8FDC3tflMS6L/96kYr6DckLnTgQZzEZWQBl3A8Kj2zCrFC9N1VgshHRBY9QIgUSa9plFK/I1AgMBAAECggEBAJ3xkBABsgWrqqWCdJ8sahJC3ZYOvSKMYmiLwCmxYkXk9IYdAhEOqV3kjkOAqkt/bnr9ibW4IvX/iyj2G7NhZjvxK5MYR7pmIshnyt1loeSx2jZurgp9d+PLC7RcltERfBpVuMeYW2SMEHF12MNimDivYyfDQAHYN5TpmPO3KM/buRkIZsfmXp3pf/55UCAbm0x5+i4g2080dpcmaPoVEuUOhU8DJkPEy1/hyCPLDkFO8EVfaJ+3AaeIdSvLcznv93KupxwcG2FaMSIfxIajEDOp8XUfXIqL97v/CaV42qgxHXBKVo+93Yf/3TK6f8POcQvNXJ9xffQo9Do9OxXQL+UCgYEA0VbLR3qTq4ODFL61tLtHGSmGs94eCrjq2MAeWaCU8US1dc/taEmSvBVF+F0q5B0BvEM3zCbIONtZYu6m/G8PF6QgxyhnpaSayStQJljbe8jblCssPeYVWSHQZ1UCJ37zj6xaynw3HKoEQm+2BcBE2kQytoMAZ1xsC1yfJwkVHfcCgYEAzHlnKQATt4Hqo74tfcvz9ACP8QUtYHdf5oy/XG+LYyxoy/kN8k5rSw2yjNVGuz/n0Z9Uzp6EJHqsTmDTpV2SbORLes67D1zKvSmE1U4fZsjsBY8iP5YePrJHT1fyM3cdavh7kBndnCWkecw7AbNRecAl33NoZtSe+ZbL58/KVjMCgYByo+d644PPH5w/VhlIOm87NmSQSAmHsbDatotoZeprHkeJly7aN8Blw/inhM4iUkhLAzyhTnPDv0v6Q9uqzl8jgTx6FIR+T+B8Xn3sIilAZsTpJaN62m/CeiQZEpK1cm6LtcWasd+0kN74SxkRmTObnFFxZdhowlJg/n4h8HViDQKBgGUDNKtUlmj5jWkG8oJK12GbRYDUBe66Cm5i6cZIdJuxvLPHfdROWULiqWpZkm++yk8MX2ETfkRnNegifWwcJdIVlhQ9PLwCI0X/1NdrmKe2aqL0av7uslJW0FOqJsS1+5p01tYBcTFKh06ETkIwy/dRrWQOJ21lbIPwsxr51ANxAoGAHyPG/NJ73dN8uyaOlxckg7GHUKWGtQ2neEj6PGJCf/sQyByb6fGMUEKoRmbXqx/L73Muki8/ibrx5qWvrV7+jrQc7xQf14BSG/bgFiB4vua3RtrCJ14xhfsYaEzXcn+WZ8+EtD0fgPSZoWeBhKg9jmvkoaOHwjWXRWC8fHw55rw=";PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));// 使用公钥加密数据Cipher encryptCipher = Cipher.getInstance("RSA");encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] encryptedBytes = encryptCipher.doFinal(originalText.getBytes());// 使用私钥解密数据Cipher decryptCipher = Cipher.getInstance("RSA");decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);String decryptedText = new String(decryptedBytes);System.out.println("加密后的数据: " + Base64.getEncoder().encodeToString(encryptedBytes));System.out.println("解密后的数据: " + decryptedText);}
}

结果如下:

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

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

相关文章

AI画师来袭:精选6款AI美女绘画软件,让创意无限

随着互联网的发展,“AIGC” 一词成为了人们热议的话题,看着 AI 生成的美丽的风景照、生活照以及一些奇观,你最开始以为这些都是真实存在的,但如果有人告诉你,这是 AI 生成的,你一定会再次感叹 AI 技术的强大…

优化医疗数据管理:Kettle ETL 数据采集方案详解

在现代医疗保健领域,数据的准确性、完整性和及时性对于提高医疗服务质量和患者护理至关重要。为了有效管理和利用医疗数据,Kettle ETL(Extract, Transform, Load)数据采集方案成为了许多医疗机构的首选工具之一。本文将深入探讨Ke…

LinkedList与链表(1万多字超级详细版本)

一. ArrayList的缺陷 上个博客已经熟悉了ArrayList的使用&#xff0c;并且进行了简单模拟实现。通过源码知道&#xff0c;ArrayList底层使用数组来存储元素&#xff1a; public class ArrayList < E > extends AbstractList < E > implements List < E &g…

C++ | Leetcode C++题解之第284题窥视迭代器

题目&#xff1a; 题解&#xff1a; template <class T> class PeekingIterator : public Iterator<T> { public:PeekingIterator(const vector<T>& nums) : Iterator<T>(nums) {flag Iterator<T>::hasNext();if (flag) {nextElement Ite…

河北省高校大数据人工智能实验室案例分享

随着大数据和人工智能技术的快速发展&#xff0c;教育领域也迎来了前所未有的变革机遇。泰迪智能科技作为一家专注于大数据与人工智能领域的高新技术企业&#xff0c;一直致力于将前沿技术引入教育行业&#xff0c;助力高校培养更多具有创新能力和实战经验的复合型人才。本次案…

VMware Cloud Foundation ESXi 主机

一、准备嵌套 ESXi 主机环境# 1)物理 ESXi 主机信息 本次准备用于部署 VCF 嵌套实验环境的物理宿主机的配置信息如下图所示。其实,部署 VCF 环境主要对内存的大小要求比较高,部署完整的管理域相关组件下来差不多就要占用 200 GB左右内存,而对 CPU 和存储的需求可以根据实…

商汤提出的BRECQ量化框架是个什么?

商汤提出的BRECQ量化框架是个什么&#xff1f; 引言 近年来&#xff0c;深度学习在多个领域取得了显著进展&#xff0c;但其巨大的计算成本和内存占用问题逐渐凸显。为了压缩和加速已训练好的网络&#xff0c;量化成为了一种重要的技术手段。量化主要分为两类&#xff1a;量化…

简洁高效的设备稼动率采集系统(一)

前言&#xff1a; 在自动化生产行业&#xff0c;每个公司都需要一款高效的生产设备&#xff0c;那我们怎么体现出设备的高效呢&#xff1f; 可以采集设备的状态&#xff0c;经过成熟的算法&#xff0c;得到设备的稼动率。设备稼动率是衡量生产设备在一定时间内真正处于生产状态…

Linux---01---安装VMware

一. 什么时Linux Linux 是一个开源的类 Unix 操作系统,Linux 是许多计算机硬件的底层操作系统&#xff0c;特别是服务器、嵌入式系统和个人电脑。它支持多种架构&#xff0c;包括 x86、x64、ARM 和 MIPS 等。Linux 因其稳定性、安全性、开源性以及广泛的社区支持而广受欢迎。 …

AvaloniaUI的学习

相关网站 github:https://github.com/AvaloniaUI/Avalonia 官方中文文档&#xff1a;https://docs.avaloniaui.net/zh-Hans/docs/welcome IDE选择 VS2022VSCodeRider 以上三种我都尝试过&#xff0c;体验Rider最好。VS2022的提示功能不好&#xff0c;VSCode太慢&#xff0c…

示例:演示如何使用系统自带System.ComponentModel.LicenseProvider 许可模块

一、目的&#xff1a;在开发过程中&#xff0c;定义许可验证的方式有很多&#xff0c;下面演示系统自带的许可验证的使用方法 LicenseProvider 是 .NET 框架中的一个类&#xff0c;用于实现组件和控件的许可机制。它允许开发者为自定义控件或组件添加许可验证&#xff0c;以确保…

当 Nginx 出现请求的乱序到达,如何处理?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; 文章目录 当 Nginx 出现请求的乱序到达&#xff0c;如何处理&#xff1f;一、理解请求乱序到达的现象二、请求乱序到达可能带来的影响三、解决方案&#xff08;一&#xf…

生物信息学新突破:在英特尔 Gaudi 2 上实现 ProtST 蛋白质语言模型加速

引言 随着人工智能技术的快速发展&#xff0c;蛋白质结构预测和语言模型在生物信息学领域扮演着越来越重要的角色。ProtST作为一种新兴的蛋白质语言模型&#xff0c;其性能在英特尔 Gaudi 2 加速器的助力下得到了显著提升。本文将探讨如何利用英特尔 Gaudi 2 加速 ProtST 模型…

JAVA简介与开发环境配置(基础介绍 一)

目录 Java 简介 主要特性 发展历史 Java开发工具 Java 开发环境配置 window系统安装java 下载JDK 配置环境变量 通过控制台测试JDK是否安装成功 Linux&#xff0c;UNIX&#xff0c;Solaris&#xff0c;FreeBSD环境变量设置 流行JAVA开发工具 使用 Eclipse 运行第一…

vue3前端开发-小兔鲜项目-登录组件的开发表单验证

vue3前端开发-小兔鲜项目-登录组件的开发表单验证&#xff01;现在开始写登录页面的内容。首先这一次完成基础的首页按钮点击跳转&#xff0c;以及初始化一些简单的表单的输入验证。后期还会继续完善内容。 1&#xff1a;首先还是准备好login页面的组件代码内容。 <script …

【Hot100】LeetCode—152. 乘积最大子数组

目录 题目1- 思路2- 实现⭐152. 乘积最大子数组——题解思路 3- ACM 实现 题目 原题连接&#xff1a;152. 乘积最大子数组 1- 思路 动规五部曲 2- 实现 ⭐152. 乘积最大子数组——题解思路 class Solution {public int maxProduct(int[] nums) {// 初始化答案以及以第一个元…

学习记录:ESP32控制舵机 FREERTOS BLE

控制舵机 PWM信号 PWM信号是一种周期性变化的方波信号&#xff0c;它有两个关键参数&#xff1a; 周期&#xff08;Period&#xff09;&#xff1a;一个完整的PWM信号的时间长度&#xff0c;通常用秒&#xff08;s&#xff09;或毫秒&#xff08;ms&#xff09;表示。占空比…

400万次服务,萝卜快跑席卷11城,时间进入全民AI时代?

ChatGPT、Midjourney、Sora、数字人…… 当我们还以为AI智能在现阶段只是对互联网造成影响时&#xff0c;出租车行业被无人驾驶汽车炸了锅。 近日&#xff0c;自动驾驶网约车“萝卜快跑”宣布其在短短几个月内&#xff0c;已经完成了超过400万次无人驾驶服务。且已在11个城市开…

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试6&…

Ruoyi-WMS本地运行

所需软件 1、JDK&#xff1a;8 安装包&#xff1a;https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.htmlopen in new window 安装文档&#xff1a;https://cloud.tencent.com/developer/article/1698454open in new window 2、Redis 3.0 安装包&a…