RSA加密、解密、签名、验签(验证签名)RSA算法原理

一、加密的原因

1.加密:是为了防止信息泄露;

2.签名:签名为了防止信息被篡改,保证数据完整性和发送方角色的可靠性和不可依赖性。

二、RSA加密简介

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

三、RSA加密、签名区别

  1. 加解密过程简述
    A和B进行通信加密,B要先生成一对RSA密钥,B自己持有私钥,给A公钥 —>A使用B的公钥加密要发送的内容,然后B接收到密文后通过自己的私钥解密内容

  2. 签名验签过程简述
    A给B发送消息,A先计算出消息的消息摘要,然后使用自己的私钥加密消息摘要,被加密的消息摘要就是签名.(A用自己的私钥给消息摘要加密成为签名)
    B收到消息后,也会使用和A相同的方法提取消息摘要,然后用A的公钥解密签名,并与自己计算出来的消息摘要进行比较–>如果相同则说明消息是A发送给B的,同时,A也无法否认自己发送消息给B的事实.(B使用A的公钥解密签名文件的过程,叫做"验签").

四、RSA原理

RSA算法常用于非对称加密,非对称加密流程如下:

(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。

五、代码实现

public class RSAUtil {public static final String SIGN_ALGORITHMS = "SHA256WithRSA";public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");/** *//*** RSA最大加密明文大小*/private static final int MAX_ENCRYPT_BLOCK = 64;/** *//*** RSA最大解密密文大小*/private static final int MAX_DECRYPT_BLOCK = 512;public static KeyPair getKeyPair() throws Exception {KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");generator.initialize(1024);return generator.generateKeyPair();}/*** 签名** @param content* @param privateKey* @return*/public static String sign(String content, String privateKey) {try {PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));KeyFactory keyf = KeyFactory.getInstance("RSA");PrivateKey priKey = keyf.generatePrivate(priPKCS8);Signature signature = Signature.getInstance(SIGN_ALGORITHMS);signature.initSign(priKey);signature.update(content.getBytes(DEFAULT_CHARSET));byte[] signed = signature.sign();return Base64.getEncoder().encodeToString(signed);} catch (Exception e) {e.printStackTrace();}return null;}/*** 验签** @param content* @param sign* @param publicKey* @return*/public static boolean verify(String content, String sign, String publicKey) {try {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] encodedKey = Base64.getDecoder().decode(publicKey);PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));Signature signature = Signature.getInstance(SIGN_ALGORITHMS);signature.initVerify(pubKey);signature.update(content.getBytes(DEFAULT_CHARSET));return signature.verify(Base64.getDecoder().decode(sign));} catch (Exception e) {e.printStackTrace();}return false;}public static PublicKey getPublicKey(String key) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(key);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey publicKey = keyFactory.generatePublic(keySpec);return publicKey;}public static PrivateKey getPrivateKey(String key) throws Exception {byte[] keyBytes = Base64.getDecoder().decode(key);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey privateKey = keyFactory.generatePrivate(keySpec);return privateKey;}/*** 公钥分段加密** @param content* @param publicKeyStr* @return* @throws Exception*/public static String publicEncrpyt(String content, String publicKeyStr) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(1, getPublicKey(publicKeyStr));byte[] bytes = content.getBytes(DEFAULT_CHARSET);int inputLen = bytes.length;int offSet = 0;byte[] cache;ByteArrayOutputStream out = new ByteArrayOutputStream();int i = 0;// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(bytes, offSet, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(bytes, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();return Base64.getEncoder().encodeToString(encryptedData);}/*** 私钥分段加密** @param content* @param privateKeyStr* @return* @throws Exception*/public static String privateEncrpyt(String content, String privateKeyStr) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(1, getPrivateKey(privateKeyStr));byte[] bytes = content.getBytes(DEFAULT_CHARSET);int inputLen = bytes.length;int offSet = 0;byte[] cache;ByteArrayOutputStream out = new ByteArrayOutputStream();int i = 0;// 对数据分段加密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(bytes, offSet, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(bytes, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();return Base64.getEncoder().encodeToString(encryptedData);}/*** 私钥分段解密** @param content* @param privateKeyStr* @return* @throws Exception*/public static String privateDecrypt(String content, String privateKeyStr) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(2, getPrivateKey(privateKeyStr));byte[] bytes = Base64.getDecoder().decode(content);int inputLen = bytes.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(bytes, offSet, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(bytes, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return new String(decryptedData);}/*** 公钥分段解密** @param content* @param publicKeyStr* @return* @throws Exception*/public static String publicDecrypt(String content, String publicKeyStr) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(2, getPublicKey(publicKeyStr));byte[] bytes = Base64.getDecoder().decode(content);int inputLen = bytes.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(bytes, offSet, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(bytes, offSet, inputLen - offSet);}out.write(cache, 0, cache.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return new String(decryptedData);}public static void main(String[] args) throws Exception {String content = "asdhaoddddddaosdjosadosaudosaudaosdusadadsadsadsadasdasdasdasdsadsadsadasdasdasdsadasdsadasdsadsadadsadsadadiugtiutujjjkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkka";// 公钥216String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCaGn5+Yq9o7kxmDS2zwIREIEkcpKbx44uPT/PX22XOjgzkMvbCEamu7KyatNhkrrSH6E14l1F739WztXffJ/OCXUmgF4egMedyGCA8ymZWbzyhwnZcywa8me8S2rjb3gkCD6VFq8BSPJx9vaMvlR7eZxe1O5lllaV6tE6SlNY7QIDAQAB";//私钥844String privateKey ="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIJoafn5ir2juTGYNLbPAhEQgSRy" +"kpvHji49P89fbZc6ODOQy9sIRqa7srJq02GSutIfoTXiXUXvf1bO1d98n84JdSaAXh6Ax53IYIDz" +"KZlZvPKHCdlzLBryZ7xLauNveCQIPpUWrwFI8nH29oy+VHt5nF7U7mWWVpXq0TpKU1jtAgMBAAEC" +"gYBOzKsk+s4EM5dnSXKo+ENmblOq43SFnzrh4+7X7vD4zZxCRH96NfEDNS4Qs45RSmmLKMOwHL2B" +"0etfWBJSPisNZomhOBgTSfvHDSIFNbvVFqQBH5zEtxIB3bPrkW5X6EDF2BYCatC70Al21kmzHr2d" +"BaL/c2p/4ueTdna/zKSKwQJBAMZLvFeyLi9jiIXXUzv7AkxF4SICtOOL56mKMkVlAXOWQgQe9FVs" +"O8lTTK6GqqLrYe5cqgTiQqcLCP8/5n33oF0CQQCoW0ospTg8JEqStTmwemF8HfgxLU6YGj5kegD2" +"Fq6HfCTq/z59THohbq6l+yoSxO3mjZb+7Zv1zu6oDR7YXFHRAkB66dEaDtFAAJNMWxc107Yt7xbI" +"zSKw9TSoy4ezqhNHQXk0MrfDB27bsS2T9NdqWzr91CRzGIi2IEn4ZfSKWmblAkB2S1bOEfV2hMWF" +"WiND9mnDDUfUPhKIW4BVl0hPodZWSouiN2DQJ8l07lF3PQjuEUNcCUb8rzYzvIgCut1eh1fRAkEA" +"qBOEqBuRq9W7vrBlHbqEk1EXu2MfeRLZWljZn6uoyedJCdSh+6neUUvqHDGi3DNdss/ByWHI9e+9" +"zOXTURmMaQ==";String s = publicEncrpyt(content, publicKey);System.out.println("公钥加密后" + s);String s1 = privateDecrypt(s, privateKey);System.out.println("解密后" + s1);//公钥加密-->私钥签名-->公钥验签-->私钥解密/* String s = publicEncrpyt(content, publicKey);System.out.println("公钥加密后"+s);//签名     AuthorizationString sign = sign(s, privateKey);System.out.println("私钥签名后:"+sign);//验签boolean verify = verify(s, sign, publicKey);System.out.println("用公钥验签后"+verify);String s1 = privateDecrypt(s, privateKey);System.out.println("解密后"+s1 );*//*String s = privateEncrpyt(content, privateKey);System.out.println("公钥加密后" + s);String sign = sign(s, privateKey);System.out.println("私钥签名后:" + sign);boolean verify = verify(s, sign, publicKey);System.out.println("用公钥验签后" + verify);String s1 = publicDecrypt(s, publicKey);System.out.println("解密后" + s1);*/}
}

六、如果上面代码还不满足你的需求也可以试试这个

   /*** @params str 要加密的字符串*/public static String rsaEncode(String str) {String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==";String outStr = "";try {// base64编码的公钥byte[] decoded = Base64.decode(publicKey, Base64.DEFAULT);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));// RSA加密Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");cipher.init(Cipher.ENCRYPT_MODE, pubKey);outStr = Base64.encodeToString(cipher.doFinal(str.getBytes("UTF-8")), Base64.DEFAULT);} catch (Exception e) {e.printStackTrace();}return outStr;}

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

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

相关文章

如何解决Windows电脑 Create folder error,Access is denied.

如何解决 Create folder error, Error: mkdir C:\Program Files\nodejs\21.1.0/: Access is denied. Waring: Name : http://npm.taobao.org/mirrors/node/v21.1.0/win-x64/node.exe Code : -2 Error : Create folder error, Error: mkdir C:\Program Files\nodejs\\21.1.0/…

【Vue原理解析】之模版编译

引言 Vue.js是一款流行的JavaScript框架,它采用了基于组件的开发模式,使得前端开发更加简单和高效。而Vue的核心功能之一就是模版解析,它负责将Vue组件中的模版代码转化为可执行的JavaScript代码。本文将深入探讨Vue模版解析的作用、核心源码…

【文末送书】如何在时间循环里最优决策?

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。关…

OpenAI调查ChatGPT故障;向量搜索的优势与局限

🦉 AI新闻 🚀 OpenAI调查ChatGPT故障,发布新AI产品GPTs和GPT-4 Turbo 摘要:OpenAI的ChatGPT和其他服务出现故障,经过调查后发现是由于DDoS攻击导致的异常流量模式。OpenAI在首届开发者大会上发布了新的AI产品GPTs&am…

CSS3 2D、3D转换

一、CSS3 2D转换&#xff1a; CSS3转换可以对元素进行移动、缩放、转动、拉长或拉伸。 2D变换的方法&#xff1a;translate()、rolate()、scale()、skew()、matrix()。 <style> div { width:200px; height:100px; background-color:red; /* Rotate div */ tran…

Linux命令(120)之tcpdump

linux命令之tcpdump 1.tcpdump介绍 linux命令tcpdump是用来将网络中传送的数据包完全截获下来以进行相关分析&#xff0c;常用的分析工具是wireshark 2.tcpdump用法 tcpdump [参数] tcpdump参数 参数说明-i指定端口-n指定协议-t在输出的每一行不打印时间戳-s抓取数据包时&a…

酷柚易汛ERP - 发货地址管理操作指南

1、应用场景 对发货地址进行管理&#xff0c;使用【物流服务】时的自动获取发货地址。 2、主要操作 打开【资料】-【发货地址管理】新增发货地址。 可以对进行地址设置及管理&#xff0c;点击【新增】可添加新的发货地址信息地址简称方便使用者在选择发货地址时&#xff0c;…

Spring集成MyBatis(自定义类和xml配置文件两种形式)

将mybatis与spring进行整合&#xff0c;主要解决的问题就是讲SqlSessionFactory对象交由spring来管理&#xff0c;所以&#xff0c;该整合&#xff0c;只需要将SqlSessionFactory的对象生成器SqlSessionFactoryBean注册在spring容器中&#xff0c;再将其注入给Dao的实现类即可完…

Lambertian模型(完美漫反射)

这里使用相乘的方式组合光照色和纹理色。根据这个模型,面朝光源的区域光照强度高,纹理色也相应增强。面背光源的区域光照弱,纹理色也被抑制。这样通过光照和纹理的结合,可以合成出具有照明效果的面部颜色,而不仅仅是固定的纹理本身的颜色。相乘方式可以近似实现不同光照方向下面…

TCP怎么实现可靠传输

链接 1&#xff0c;TCP头部的校验和保证获取正确数据&#xff0c;防篡改&#xff1b; 2&#xff0c;序列号和ACK确认机制同于管理数据包&#xff0c;对接收到的数据包进行确认&#xff0c;对没有接收到的数据包进行重传&#xff1b; 3&#xff0c;重传机制&#xff0c;包括超…

MongoDB副本集配置和创建

副本集有三类角色&#xff1a;master(primary)&#xff0c;slave(secondary)&#xff0c;仲裁服务器。 primary是主&#xff0c;只有primary能写入&#xff0c;secondary无法插入数据&#xff0c;且需要声明是slave才能查看数据 一般生产搞三个服务器做一个master和两个slave&a…

树状数组:leetcode307 区域和检索

307. 区域和检索 - 数组可修改 给你一个数组 nums &#xff0c;请你完成两类查询。 其中一类查询要求 更新 数组 nums 下标对应的值另一类查询要求返回数组 nums 中索引 left 和索引 right 之间&#xff08; 包含 &#xff09;的nums元素的 和 &#xff0c;其中 left < ri…

成都优优聚美团代运营:打造高效电商运营的利器

一、引人注目的标题 在繁杂的电商市场中&#xff0c;成都优优聚美团代运营以其专业的服务&#xff0c;为商家提供了一站式的解决方案。那么&#xff0c;这个备受瞩目的代运营平台有何特别之处呢&#xff1f;今天&#xff0c;我们就来一探究竟。 二、平台背景与优势 成都优优聚…

前端如何把图片url地址https://url转成base64

前端如何把图片url地址https://url转成base64 一、直接上代码 一、直接上代码 async getImgImg() {let url await this.base64(this.From.imageData) }&#xff0c; base64(url) {return new Promise(resolve > {const image new Image()// 先设置图片跨域属性image.cros…

JL-03小型气象站气象环境在线监测设备自动上传并保存数据

JL-03小型气象站产品概述 小型气象站用于对风速、风向、雨量、空气温度、空气湿度、太阳辐射、光照强度、土壤温度、土壤湿度、蒸发量、大气压力等气象要素进行现场监测。既可以通过无线通讯将数据传送至云平台&#xff0c;又可以通过配套的数据采集通讯线与计算机进行连接&am…

C/C++内嵌简本语言-LUA

一、LUA简介 Lua [1] 是一个小巧的脚本语言。Lua脚本可以很容易的被C/C 代码调用&#xff0c;也可以反过来调用C/C的函数&#xff0c;这使得Lua在应用程序中可以被广泛应用。不仅仅作为扩展脚本&#xff0c;也可以作为普通的配置文件&#xff0c;代替XML,ini等文件格式&#…

1. 深度学习——激活函数

机器学习面试题汇总与解析——激活函数 本章讲解知识点 什么是激活函数&#xff1f; 为什么要使用激活函数&#xff1f; 详细讲解激活函数 本专栏适合于Python已经入门的学生或人士&#xff0c;有一定的编程基础。本专栏适合于算法工程师、机器学习、图像处理求职的学生或人…

一分钟秒懂人工智能对齐

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

C语言的部分逆置

部分逆置 pta c语言&#xff1a; #include <stdio.h>void reverse(int arr[], int start, int end) {while (start < end) {int temp arr[start];arr[start] arr[end];arr[end] temp;start;end--;} }int main() {int n, m;scanf("%d%d", &n, &m…

C++文件的读取和写入

1、C对txt文件的读&#xff0c;ios::in #include<iostream> #include<fstream> using namespace std;int main() {ifstream ifs;ifs.open("test.txt",ios::in);if(!ifs.is_open()){cout<<"打开文件失败&#xff01;"<<endl;}char…