RSA加解密简单实现

news2024/11/17 13:46:15

目录

浅谈加解密实现方式

MD5加密

DES加密

AES加密

RSA加密

SSL加密认证

关于RSA加解密实现

简单数据加解密的实现

分块加解密实现

附录


浅谈加解密实现方式

关于数据加解密方式,我们一般分为不可逆加密、对称可逆加密、非对称加密、综合加密应用等,简单介绍下我所了解的一些加密方式。

MD5加密

MD5加密属于不可逆加密,原文加密过后生成的密文无法解密出原文。

其特点包括:

  • 相同原文加密结果一致
  • 不同长度的内容加密过后都是32位
  • 原文差别很小,密文差别很大
  • 不管文件多大,都能产生32位长度摘要,文件内容不变,名字变了,密文不会变

一般使用场景包括:

  • 防止被篡改:校验数据是否一致、源代码管理器
  • 防止明文存储:密码保存
  • 防止抵赖:数字签名

DES加密

DES加密属于对称可逆加密,通信的双方使用同一个秘钥,通过秘钥加密过后的密文,可使用秘钥解密出原文。

其特点包括:

  • 加密解密速度快,但密匙的安全问题有待解决
  • 不具有个体原子性,一个密钥被共享,泄露几率会大大增加
  • 适合大量数据

一般用于资讯传输数据的加密

AES加密

AES加密属于对称可逆加密,通信的双方使用同一个秘钥,通过秘钥加密过后的密文,可使用秘钥解密出原文。安全性高于DES加密

一般用于数据库加密存储隐私数据

其特点包括:

  • 加密简单快速,但不具有个体原子性,一个密钥被共享,泄露几率会大大增加
  • 适合大量数据
  • 可利于并行计算
  • 分为不同的工作模式,ECB,CBC,OFB,CFB,CFB8,CTR,GCM,除了ECB无须设置初始化向量IV而不安全之外,其它AES工作模式都必须设置向量IV

RSA加密

RSA属于非对称可逆加密,加密秘钥和解密秘钥为两个不同的秘钥,两个秘钥称之为公钥和私钥,公钥是公开的,通信双方都持有的,用来加密原文数据;私钥为通信的其中一方持有,用来解密数据来获取原文数据。

其特点包括:

  • 公钥和私钥是一对
  • 公钥和私钥不可相互推导,只有密文,没有解密key,也推导不出原文
  • 加解密速度慢,安全性好

一般用于网络数据传输,从而保证信息的保密性、认证性,比如数字签名,即私钥持有者对信息进行签名,验证者可以根据公开的公钥进行验证签名是否正确和有效,即实现了认证性,以及不可抵赖性。

SSL加密认证

SSL加密是数字证书加密,属于加解密综合应用,https协议使用(https协议=HTTP协议+SSL/TLS协议)

其证书构成为:

  • 持有者姓名
  • 发证机关
  • 有效期
  • 证书持有人公钥
  • 扩展信息
  • 发证机关对该证书的数字签名(数字签名=前5点信息MD5摘要,然后用CA的私钥加密下)

SSL加密模式可以用于发送安全电子邮件、访问安全站点、网上招标与投标、网上签约、网上订购、安全网上公文传送、网上办公、网上缴费、网上缴税以及网上购物等安全的网上电子交易活动,交易时,双方需要使用数字签名来表明自己的身份,并使用数字签名来进行有关的交易操作,防止交易过程中出现数据被泄露或篡改的情况

关于RSA加解密实现

使用RSA加解密的实现,需要引用System.Security.Cryptography

简单数据加解密的实现

public void RSACheck(string txtValue)
        {
            var rsaClient = new RSACryptoServiceProvider(2048);
            var privakeKeyByte = rsaClient.ExportRSAPrivateKey();
            var publicKeyByte = rsaClient.ExportRSAPublicKey();
            string privateKey = Convert.ToBase64String(privakeKeyByte); 
            string publicKey= Convert.ToBase64String(publicKeyByte);

            int privateBytesRead = 0;
            RSACryptoServiceProvider rsaPrivate = new RSACryptoServiceProvider();
            rsaPrivate.ImportRSAPrivateKey(privakeKeyByte, out privateBytesRead);
            int publicBytesRead = 0;
            RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();
            rsaPublic.ImportRSAPublicKey(publicKeyByte, out publicBytesRead);

            Console.WriteLine("原始字符串:" + txtValue);
            //公钥加密
            string enStr = Convert.ToBase64String(rsaPublic.Encrypt(System.Text.Encoding.UTF8.GetBytes(txtValue), RSAEncryptionPadding.Pkcs1));
            Console.WriteLine("加密字符串:" + enStr);
            //私钥解密
            string deStr = System.Text.Encoding.UTF8.GetString(rsaPrivate.Decrypt(Convert.FromBase64String(enStr),RSAEncryptionPadding.Pkcs1));
            Console.WriteLine("解密字符串:" + deStr);
            私钥签名
            //string signStr = rsa.Sign(txtValue);
            //Console.WriteLine("字符串签名:" + signStr);
            公钥验证签名
            //bool signVerify = rsa.Verify(txtValue, signStr);
            //Console.WriteLine("验证签名:" + signVerify);
        }

实现效果

分块加解密实现

 RSA加解密数据时,对于加解密的数据长度有一定的限制,其长度规则限制为

需要加密的字节数不能超过密钥的长度值除以 8 再减去 11(RSACryptoServiceProvider.KeySize / 8 - 11),而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)

因此对于加密/解密数据长度超过最大长度限制时,使用分块加密/解密的方式

分块加密实现

        /// <summary>
        /// 获取RSA私钥加密数据
        /// </summary>
       /// <param name="publicKey">加密公钥</param>
       /// <param name="txtValue">加密原文数据</param>
        /// <returns></returns>
        public string GetRSAEncrypt(string publicKey,string txtValue)
        {
            byte[] publicKeyByte = Convert.FromBase64String(publicKey);
            int publicBytesRead = 0;
            RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();
            rsaPublic.ImportRSAPublicKey(publicKeyByte, out publicBytesRead);
            int maxBlockSize = rsaPublic.KeySize / 8 - 11;//加密块最大长度限制
            //公钥加密
            string enStr = "";
            byte[] jsonByte = System.Text.Encoding.UTF8.GetBytes(txtValue);
            if (jsonByte.Length <= maxBlockSize)
            {
                enStr = Convert.ToBase64String(rsaPublic.Encrypt(jsonByte, RSAEncryptionPadding.Pkcs1));
            }
            else
            {
                //待加密的字节数不能超过密钥的长度值除以 8 再减去 11(即:RSACryptoServiceProvider.KeySize / 8 - 11),
                //而加密后得到密文的字节数,正好是密钥的长度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)。
                //加密数据长度超过最大长度限制时,使用分块加密的方式
                using (MemoryStream plaiStream = new MemoryStream(jsonByte))
                using (MemoryStream crypStream = new MemoryStream())
                {
                    byte[] buffer = new byte[maxBlockSize];
                    int blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
                    while (blockSize > 0)
                    {
                        byte[] toEncrypt = new byte[blockSize];
                        Array.Copy(buffer, 0, toEncrypt, 0, blockSize);
                        byte[] cryptograph = rsaPublic.Encrypt(toEncrypt, RSAEncryptionPadding.Pkcs1);
                        crypStream.Write(cryptograph, 0, cryptograph.Length);
                        blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
                    }
                    enStr = Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
                }
            }
            return enStr;
        }

分块解密实现

        /// <summary>
        /// RSA解密
        /// </summary>
        /// <param name="cipherText">密文数据</param>
        /// <param name="privateKey">解密私钥</param>
        /// <returns></returns>
        public string DeRsaData(string cipherText, string privateKey)
        {
            string deStr = "";
            int bytesRead = 0;
            RSACryptoServiceProvider rsaPrivate = new RSACryptoServiceProvider();
            rsaPrivate.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out bytesRead);
            int maxBlockSize = rsaPrivate.KeySize / 8; //解密块最大长度限制
            byte[] ciphertextData = Convert.FromBase64String(cipherText);
            if (ciphertextData.Length <= maxBlockSize)
            {
                deStr = System.Text.Encoding.UTF8.GetString(rsaPrivate.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1));
            }
            else
            {
                //需要解密的数据长度超过解密块最大长度时,使用分块解密
                using (MemoryStream crypStream = new MemoryStream(ciphertextData))
                using (MemoryStream plaiStream = new MemoryStream())
                {
                    byte[] buffer = new byte[maxBlockSize];
                    int blockSize = crypStream.Read(buffer, 0, maxBlockSize);
                    while (blockSize > 0)
                    {
                        byte[] toDecrypt = new byte[blockSize];
                        Array.Copy(buffer, 0, toDecrypt, 0, blockSize);
                        byte[] plaintext = rsaPrivate.Decrypt(toDecrypt, RSAEncryptionPadding.Pkcs1);
                        plaiStream.Write(plaintext, 0, plaintext.Length);
                        blockSize = crypStream.Read(buffer, 0, maxBlockSize);
                    }
                    deStr = System.Text.Encoding.UTF8.GetString(plaiStream.ToArray());
                }
            }
            return deStr;
        }

附录

关于System.Security.Cryptography的使用学习AesCryptoServiceProvider 类 (System.Security.Cryptography) | Microsoft Learn

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

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

相关文章

魔改并封装 YoloV5 Version7 的 detect.py 成 API接口以供 python 程序使用

文章目录IntroductionSection 1 起因Section 2 魔改的思路Section 3 代码Part 1 参数部分Part 2 识别 APIPart 3 完整的 DetectAPI.pyPart 4 修改 dataloaders.pySection 4 调用ReferenceIntroduction YoloV5 作为 YoloV4 之后的改进型&#xff0c;在算法上做出了优化&#xf…

errgroup 原理简析

golang.org/x/sync/errgroup errgroup提供了一组并行任务中错误采集的方案。 先看注释 Package errgroup provides synchronization, error propagation, and Context cancelation for groups of goroutines working on subtasks of a common task. Group 结构体 // A Gro…

Sphinx : 高性能SQL全文检索引擎

Sphinx是一款基于SQL的高性能全文检索引擎&#xff0c;Sphinx的性能在众多全文检索引擎中也是数一数二的&#xff0c;利用Sphinx&#xff0c;我们可以完成比数据库本身更专业的搜索功能&#xff0c;而且可以有很多针对性的性能优化。 Sphinx的特点 快速创建索引&#xff1a;3分…

Barra模型因子的构建及应用系列三之Momentum因子

一、摘要 在之前的Barra模型系列文章中&#xff0c;我们已经初步讲解、构建了Size因子和Beta因子&#xff0c;并分别创建了对应的单因子策略。通过回测发现&#xff0c;其中Size因子的小市值效应具有很强的收益能力。而本篇文章将在该系列下进一步构建Momentum因子。 二、模型…

90%企业在探索的敏捷开发怎么做?极狐GitLab总结了这些逻辑与流程

本文来自&#xff1a; 彭亮 极狐(GitLab) 高级产品经理 毛超 极狐(GitLab) 研发工程师 极狐(GitLab) 市场部内容团队 “敏捷” 是指能够驾驭变化&#xff0c;保持组织竞争优势的一种能力。自 2001 年《敏捷宣言》以来&#xff0c;敏捷及敏捷开发理念逐渐席卷全球。中国信通院《…

面试已上岸,成功拿到阿里和腾讯的入职offer,Java程序员面经全在这了,希望能帮到你!

前言 一开始的时候简历海投大多数都被拒绝了&#xff0c;后来自己找在腾讯上班的朋友帮忙改了一下简历&#xff0c;果然不一样了大多都能拿到面试机会&#xff0c;当然拿到后也没有那么顺利&#xff0c;面了差不多有十几家公司的样子&#xff0c;大大小小的都有&#xff0c;其中…

C++和QML混合编程_QML发送信号到C++端(信号和槽绑定)

C和QML混合编程_QML发送信号到C端&#xff08;信号和槽绑定&#xff09; 前言&#xff1a; 下面是之前讲解过的三种方法 1、使用Q_INVOKABLE声明一下普通函数&#xff0c;在QML端可以直接调用 2、使用Connections绑定QML的信号和C端的槽函数 3、使用connect绑定QML的信号和C端的…

通俗易懂理解——布隆过滤器

文章目录概述本质优缺点优点&#xff1a;缺点&#xff1a;实际应用解决redis缓存穿透问题&#xff1a;概述 本质 本质&#xff1a;很长的二进制向量&#xff08;数组&#xff09; 主要作用&#xff1a;判断一个数据在这个数组中是否存在&#xff0c;如果不存在为0&#xff0c…

NR PDCP duplication

欢迎关注同名微信公众号“modem协议笔记”。 PDCP duplication 是PDCP 的一个功能&#xff0c;主要是为满足URLLC 场景的可靠性/延迟要求&#xff0c;而产生的一种提高传输可靠性的机制&#xff0c;具体就是在信号状况比较差的情况下&#xff0c;网络侧通过配置PDCP duplicati…

集中式存储和分布式存储

分布式存储是相对于集中式存储来说的&#xff0c;在介绍分布式存储之前&#xff0c;我们先看看什么是集中式存储。不久之前&#xff0c;企业级的存储设备都是集中式存储。所谓集中式存储&#xff0c;从概念上可以看出来是具有集中性的&#xff0c;也就是整个存储是集中在一个系…

Zynq非Video Mixer方案实现视频叠加输出,无需SDK配置,提供工程源码和技术支持

目录1、前言2、Video Mixer的不便之处3、FDMA取代Video Mixer实现视频叠加输出4、Vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 关于Zynq使用Video Mixer方案实现视频叠加输出方案请参考点击查看&#xff1a;Video Mixer方案 对于Zynq和Micr…

Elasticsearch:Security API 介绍

在我之前的文章 “Elasticsearch&#xff1a;运用 API 创建 roles 及 users” &#xff0c;我展示了如何使用 Security API 来创建用户及角色来控制访问 Elasticsearch 中的索引。在今天的文章中&#xff0c;我将展示一个使用 Security API 来创建一个用户及角色来访问一个索引…

双指针【灵神基础精讲】

来源0x3f&#xff1a;https://space.bilibili.com/206214 文章目录同向双指针[209. 长度最小的子数组](https://leetcode.cn/problems/minimum-size-subarray-sum/)[713. 乘积小于 K 的子数组](https://leetcode.cn/problems/subarray-product-less-than-k/)[3. 无重复字符的最…

计算机相关专业毕业论文选题推荐

计算机科学以下是我推荐的20个计算机科学专业的本科论文选题&#xff1a;基于机器学习的推荐算法研究与实现基于区块链技术的数字身份认证方案设计与实现基于深度学习的图像识别技术研究与应用基于虚拟现实技术的教育培训平台设计与实现基于物联网技术的智能家居系统研究与开发…

Dubbo与Spring Cloud优缺点分析(文档学习个人理解)

文章目录核心部件1、总体框架1.1 Dubbo 核心部件如下1.2 Spring Cloud 总体架构2、微服务架构核心要素3、通讯协议3.1 Dubbo3.2 Spring Cloud3.3 性能比较4、服务依赖方式4.1 Dubbo4.2 Spring Cloud5、组件运行流程5.1 Dubbo5.2 Dubbo 运行组件5.3 Spring Cloud5.4 Spring Clou…

[数据治理-02]一个例子搞懂元数据、参考数据、主数据、交易数据...的关系

杜威说过“所有知识都是分类”&#xff01;很好理解&#xff0c;分类是认知经济&#xff0c;任何有效分类&#xff0c;都可以极大地节省我们的认知精力。谈到数据就必须做个分类&#xff0c;谈到数据分类可以从多个维度出发&#xff0c;比如按业务维度、这是财务数据、那是人力…

C++ ——多态 下 (图解多态原理、虚函数的再认知)

目录 一、抽象类 1&#xff09;抽象类定义 2&#xff09;抽象类的继承 3&#xff09;抽象类实现多态 4&#xff09;抽象类的好处 二、多态的实现原理 1&#xff09;虚函数的存储方式 2&#xff09;子类中虚函数的存储方式 ① 子类将基类中的虚表原封不动的拷贝到自己的…

【原创】java+swing+mysql教师管理系统设计与实现

教师管理系统主要是方便学校对教师进行管理&#xff0c;本文主要介绍如何使用java的swing窗体控件和mysql数据库去设计一个简单的教师管理系统。 功能分析&#xff1a; 本系统为javaswingmysql的教师管理系统&#xff0c;管理员、教师 功能如下&#xff1a; 管理员&#xff…

Quartz入门教程

本文参考文章编写 Quartz 官网 Quartz 是 OpenSymphony 开源组织在 Job Scheduling 领域又一个开源项目&#xff0c;是完全由 Java 开发的一个开源任务日程管理系统&#xff0c;“任务进度管理器”就是一个在预先确定&#xff08;被纳入日程&#xff09;的时间到达时&#xff…

2022——寒假总结

文章目录背景报名摸索结果总结背景 大一上学期&#xff0c;刚上大学没有尽快适应&#xff0c;什么都没有学到。 因为疫情&#xff0c;所以平时的测试以及期末都是线上进行的&#xff0c;就没怎么认真学&#xff0c;网课直接划水。 我的生活与学习很不平衡&#xff0c;还热衷于参…