Java对称与非对称加密解密(AES与RSA)

尽可能预想所有残酷的可能性、因为现实永远让你无法预警,而且又吝于给人慈悲。——富坚义博

 今天我们讨论一下秘钥这个东西


一、对称加密技术与非对称加密技术简述

 加密技术可以分为对称与非对称两种。

对称加密、解密即加密与解密用的是同一把秘钥,常用的对称加密技术有DES,AES等。

而非对称技术的加密与解密用的是不同的秘钥,常用的非对称加密技术有RSA等。

二、对称加密技术与非对称加密技术的使用场景简述

为什么要有非对称加密,解密技术呢?

假设这样一种场景A要发送一段消息给B,但是又不想以明文发送,所以就需要对消息进行加密。如果采用对称加密技术,那么加密与解密用的是同一把秘钥,除非B事先就知道A的秘钥,并且保存好,这样才可以解密A发来的消息。

由于对称技术只有一把秘钥,所以秘钥的管理是一个很麻烦的问题,而非对称技术的诞生就解决了这个问题,非对称加密与解密使用的是不同的秘钥,并且秘钥对是一一对应的,即用A的私钥加密的密文只有用A的公钥才能解密。

这样的话,每个人都有两把秘钥,私钥和公钥,私钥是只有自己才知道的,不能告诉别人,而公钥是公开的,大家都可以知道。这样,当A想要发送消息给B的时候,只需要用B的公钥对消息进行加密就可以了,由于B的私钥只有B才拥有,所以A用B的公钥加密的消息只有B才能解开。而B想更换自己的秘要时也很方便,只须把公钥告诉大家就可以了。

那么,既然非对称加密如此之好,对称加密就没有存在的必要了吗,其实不然,由于非对称加密算法的开销很大,所以如果直接以非对称技术来加密发送的消息效率会很差。那么怎么办呢?解决的办法也很简单,就是把对称加密技术与非对称加密技术结合起来使用。

还是这个例子:

第一个场景(公钥加密):A要发送一个消息给B。

第一步:A先 生成一个对称秘钥,这个秘钥可以是随机生成的;

第二步:A用B的公钥加密第一步生成的这个对称秘钥; (事先生成公钥、私钥)

第三步:A把加密过的对称秘钥发给B; (Aes秘钥发给B)

第四步:A用第一步生成的这个对称秘钥加密实际要发的消息 (用aes加密)

第五步:A把用对称秘钥加密的消息发给B (加密内容发给B)

对于B

他先收到A发来的对称秘钥,这个秘钥是用B的公钥加密过的,所以B需要用自己的私钥来解密这个秘钥,

然后B又收到A发来的密文,这时候用刚才解密出来的秘钥来解密密文

这样子的整个过程既保证了安全,又保证了效率。

第二个场景(私钥加密):B要发送一个消息给A。

第一步:B先生成一个对称秘钥,这个秘钥可以是随机生成的;

第二步:B用自己的私钥加密第一步生成的这个对称秘钥;

第三步:B把加密过的对称秘钥发给A;

第四步:B用第一步生成的这个对称秘钥加密实际要发的消息

第五步:B把用对称秘钥加密的消息发给A

对于A

他先收到B发来的对称秘钥,这个秘钥是用B的私钥加密过的,所以A需要用B的公钥来解密这个秘钥,

然后A又收到B发来的密文,这时候用刚才解密出来的秘钥来解密密文

这样子的整个过程既保证了安全,又保证了效率。

三、Java实现使用的是AES的对称加密和RSA的非对称加密

接下来是Java实现:

我这个Java实现使用的是AES的对称加密和RSA的非对称加密(DES的对称加密实现方法和AES的是一样的,但是由于DES算法本身有缺陷,容易被破解,所以现在多用其升级版AES对称加密)

AES加密工具类封装

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;/*** 〈Function overview〉<br>** @className: AESUtil* @package: com.soft.team.base.encryption* @author: yuanzf* @date: 2022/3/16 16:41*/
public class AESUtil {/**** home.php?mod=space&uid=952169 str 加密前数据* @param key 对称密钥,必须为16位* home.php?mod=space&uid=155549 返回加密后数据*/public static String encrypt(String str,String key){AES aes = SecureUtil.aes(key.getBytes());return aes.encryptBase64(str);}/**** @param str 加密后的数据* @param key 盐,必须为16位* @return 返回解密后数据*/public static String decrypt (String str,String key){AES aes = SecureUtil.aes(key.getBytes());return aes.decryptStr(str);}
}

RSA加密工具类封装

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyPair;/*** 〈Function overview〉<br>** @className: RSA* @package: com.soft.team.base.encryption* @author: yuanzf* @date: 2022/3/16 15:02*/
public class RSAUtil {private String publicKey;private String privateKey;/*有参构造方法,加解密时使用。公钥加密需用私钥解密,私钥加密需用公钥解密*/public RSAUtil(String publicKey,String privateKey){this.publicKey = publicKey;this.privateKey = privateKey;}/*无参构造方法,新建密钥对时使用*/public RSAUtil(){KeyPair pair = SecureUtil.generateKeyPair("RSA");publicKey = new String(Base64.encodeBase64(pair.getPublic().getEncoded()));privateKey= new String(Base64.encodeBase64((pair.getPrivate().getEncoded())));}/**** @param str 加密前数据* @return 返回加密后数据*/public String encrypt(String str){return SecureUtil.rsa(privateKey,publicKey).encryptBcd(str, privateKey!=null?KeyType.PrivateKey:KeyType.PublicKey);}/**** @param str 加密后的数据* @return 返回解密后数据*/public String decrypt (String str){return SecureUtil.rsa(privateKey,publicKey).decryptStrFromBcd(str, privateKey!=null?KeyType.PrivateKey:KeyType.PublicKey);}public String getPublicKey() {return publicKey;}public String getPrivateKey() {return privateKey;}
}

测试类

import cn.hutool.core.util.RandomUtil;
import org.junit.Test;/*** 加解密测试类* @author: song rose roy nba*/
public class SerialUtilTest {/*** 测试方法* 使用公钥加密就必须使用私钥解密,使用私钥加密就必须使用公钥解密* 以下测试方式编写了私钥加密公钥解密,公钥加密私钥解密两种情况* 真实的业务场景一方持有私钥,一方持有公钥。因此不会存在两种密钥在一个线程里加解密的情况* 真实场景应该是加密方式一和解密方式二为一方,加密方式二和解密方式一为一方*/@Testpublic void start(){/*获取aes对称密钥*/String aesKey = getRandomKey();System.out.println("我是aes对称密钥,请将我保存:"+aesKey);/*使用aes密钥对内容进行加密*/String content = AESUtil.encrypt("我是一封信,请将我加密后发送",aesKey);System.out.println("我是加密后的内容:"+content);/*生成rsa密钥对*/RSAUtil rsa = new RSAUtil();System.out.println("我是rsa公钥,请将我保存:"+rsa.getPublicKey());System.out.println("我是rsa私钥,请将我保存:"+rsa.getPrivateKey());/*rsa加密方式一 公钥加密,在第一个参数放入生成的公钥*/RSAUtil rsaUtil1 = new RSAUtil(rsa.getPublicKey(),null);String enContent1 = rsaUtil1.encrypt(aesKey);System.out.println("我是经过rsa公钥加密后的aes对称密钥,请将我保存:"+enContent1);/*rsa加密方式二 私钥加密,在第二个参数放入生成的私钥*/RSAUtil rsaUtil2 = new RSAUtil(null,rsa.getPrivateKey());String enContent2 = rsaUtil2.encrypt(aesKey);System.out.println("我是经过rsa私钥加密后的aes对称密钥,请将我保存:"+enContent2);/*解密方式一 私钥解密*/String deContent1 = rsaUtil2.decrypt(enContent1);System.out.println("我是经过rsa私钥解密后的aes对称密钥,请将我保存:"+deContent1);System.out.println("我是解密后的内容:"+AESUtil.decrypt(content,deContent1));/*解密方式二 公钥解密*/String deContent2 = rsaUtil2.decrypt(enContent1);System.out.println("我是经过rsa公钥解密后的aes对称密钥,请将我保存:"+deContent2);System.out.println("我是解密后的内容:"+AESUtil.decrypt(content,deContent2));}/*** 随机生成aes的秘钥*/private String getRandomKey() {return RandomUtil.randomString(16);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务springcloud 10.config配置中心框架和rabbitmq的安装

config配置中心的作用&#xff1a;项目的yml 配置文件保存到 git 服务器&#xff0c;例如 github.com 或 gitee.com 微服务启动时&#xff0c;从服务器获取配置文件 1.新建 “Project”,命名为 config。注意这里的不是maven项目&#xff0c;而是project 2.将sp02,sp03,sp04,s…

Docker: 改变容器化世界的革命性技术

目录 1.1什么是虚拟化 1.2什么是Docker 1.3容器与虚拟机的比较 1.4Docker组建 2、Docker安装 2.2设置ustc的镜像 2.3Docker的启动与停止 3、docker常用命令 3.1镜像 3.2容器相关命令 1.1什么是虚拟化 在计算机中&#xff0c;虚拟化&#xff08;Vitualization&#x…

netty学习(1):1个客户端与服务器通信

1. 新建maven工程&#xff0c;添加netty依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"…

Spring MVC

Spring MVC &#x1f50e;什么是 Spring MVCMVC对比 MVC 与 Spring MVC &#x1f50e;Spring MVC—连接RequestMapping 默认情况下支持的请求类型RequestMapping 指定请求类型 &#x1f50e;Spring MVC—获取参数获取单个参数获取两个参数参数重命名传递对象传递 JSON 对象获取…

访问学者申请英语口语怎样顺利通关

想要成功申请成为访问学者&#xff0c;英语口语的流利表达是非常重要的。下面知识人网小编整理的一些帮助你顺利通关的建议&#xff1a; 1. 提前准备&#xff1a;在面试之前&#xff0c;充分准备各种常见问题的回答。练习口语表达&#xff0c;加强词汇和语法的掌握。可以通过与…

CSS实现多头像叠加ui效果

第一种实现方式 简单粗暴直接使用margin-right实现&#xff0c;缺点是第一行右侧最右边头像溢出容器&#xff0c;代码中的三行注释的代码放开后可解决这个问题。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…

时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测

时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测 目录 时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络股票价格预测效果一览基本介绍研究过程程序设计参考资料效果一览 基本介绍 时序预测 | MATLAB实现BO-LSTM贝叶斯优化长短期记忆神经网络…

postman自动生成接口文档

点击&#xff1a; 会自动生成一个文件夹 点击图表&#xff0c;修改名字 新建一个请求&#xff0c;到时候会自动保存到文件夹里面&#xff0c;但是保存前看清楚保存的名字 点击三个点-》点击export即可

Excel - Windows操作系统下的键盘快捷方式

注意&#xff1a; * 这些快捷方式指的是美式键盘布局。 其他键盘布局的键可能与美式键盘上的键不完全对应。 * 快捷方式中的加号 () 表示需要同时按多个键。 * 快捷方式中的逗号 (,) 表示需要按顺序按多个键。 * 如果经常使用的操作没有快捷键&#xff0c;则可以“录制宏”…

英语语法学习_incomplete

在语言学中&#xff0c;自然语言的语法是说话者或作者在从句、短语和单词的构成上的一套结构约束。1 「语法」实际上有两个概念&#xff0c;一是「语法」&#xff08;也叫「文法」&#xff09;&#xff0c;二是「语法学」。 一、语法&#xff1a;客观存在的语言结构规律&#x…

Oracle 实现A表B表字段/表名不同,定时任务+存储过程,定期执行增删改查

说明 假设Oracle A表B表 &#xff0c;表字段不同&#xff0c;表名也不同&#xff0c; 通过存储过程 定时任务(Jobs)&#xff0c; 定期去执行业务逻辑的增删改查 。 1、定时同步 创建一个存储过程&#xff0c;用于比较两张表中的数据&#xff0c;并根据状态决定需要同步的数据。…

ChatGPT微调系列一:微调 流程

文章目录 前言一、啥叫微调二、为啥要微调三、不是所有模型都可以微调的四、总述微调的基本流程&#xff0c;以及涉及的主要函数&#xff0c;参数1. 安装2. 准备训练数据3. openai.api_key os.getenv() 进行一个说明4. 通过API 调用模型 常用函数5. 微调模型 常用函数6. OpenA…