首页 > 其他分享 >RSA加解密笔记

RSA加解密笔记

时间:2024-07-19 16:31:24浏览次数:15  
标签:Convert string 加解密 RSA 笔记 ToBase64String ----- privateKeyParam ToByteArrayUnsign

        前文介绍了SM国产的对称加密算法介绍,这里记录一下RSA 非对称加密情况, 不太情况贸然上手还是有一些坑,密钥位数分为512,1024,2048, 4096 之类,

公钥,私钥成对出现,一般文本之类,如请求参数而言,公钥加密,私钥解密, 如果是证书,情况会稍微不同,这里不展开记录,

比如:双方对接数据的时候,各自掌握一对密钥,只需要提供给对方公钥即可,发送数据时对公钥进行加密,收到数据时用私钥进行解密,不用担心数据泄露,毕竟只有公钥是无法进行解密

RSA密钥分为 PKCS1 ,PKCS8 格式, 两种格式的公钥都是以 -----BEGIN PUBLIC KEY----- 开头,-----END PUBLIC KEY----- 结尾,

不同的是私钥,PKCS1 格式的开头和结束都会多一个 RSA ,PKCS8更通用一些

实际交互的时候,可能会将PEM模式的的密钥转换成XML 格式的进行处理,使用 RsaKeyParameters,PublicKeyFactory 这两个对象即可

        public static string RSAPrivateKeyToXml(string privateKey)
        {
            privateKey = privateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\n", "").Replace("\r", "");
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        public static string RSAPublicToXml(string pem)
        {
            pem = pem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(pem));
            string xmlPub = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
            Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
            return xmlPub;
        }

此外加密,解密如下

        /// <summary> 
        /// RSA 加密
        /// </summary> 
        /// <param name="encryptString" >明文</param> 
        /// <param name="publicKey" >公钥</param> 
        public static string RSAEncrypt(string encryptString, string publicKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(publicKey);
            byte[] encryptByte = Encoding.UTF8.GetBytes(encryptString);
            int maxSize = rsa.KeySize / 8 - 11;
            if (encryptByte.Length <= maxSize)
            {
                byte[] cipherbytes = rsa.Encrypt(encryptByte, false);
                return Convert.ToBase64String(cipherbytes);
            }
            else
            {
                using (MemoryStream plaiStream = new MemoryStream(encryptByte))
                using (MemoryStream crypStream = new MemoryStream())
                {
                    byte[] buffer = new byte[maxSize];
                    int blockSize = plaiStream.Read(buffer, 0, maxSize);
                    while (blockSize > 0)
                    {
                        byte[] ToEncrypt = new byte[blockSize];
                        Array.Copy(buffer, 0, ToEncrypt, 0, blockSize);
                        byte[] Cryptograph = rsa.Encrypt(ToEncrypt, false);
                        crypStream.Write(Cryptograph, 0, Cryptograph.Length);
                        blockSize = plaiStream.Read(buffer, 0, maxSize);
                    }
                    return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
                }
            }
        }


        /// <summary> 
        /// RSA 解密
        /// </summary> 
        /// <param name="decryptString">密文</param> 
        /// <param name="privateKey">私钥</param> 
        public static string RSADecrypt(string decryptString, string privateKey)
        {
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(privateKey);

            int maxSize = rsa.KeySize / 8;
            byte[] decryptByte = Convert.FromBase64String(decryptString);
            if (decryptByte.Length <= maxSize)
            {
                byte[] cipherbytes = rsa.Decrypt(decryptByte, false);
                return Encoding.UTF8.GetString(cipherbytes);
            }
            else
            {
                using (MemoryStream crypStream = new MemoryStream(decryptByte))
                using (MemoryStream plaiStream = new MemoryStream())
                {
                    byte[] buffer = new byte[maxSize];
                    int blockSize = crypStream.Read(buffer, 0, maxSize);

                    while (blockSize > 0)
                    {
                        byte[] toDecrypt = new byte[blockSize];
                        Array.Copy(buffer, 0, toDecrypt, 0, blockSize);

                        byte[] plaintext = rsa.Decrypt(toDecrypt, false);
                        plaiStream.Write(plaintext, 0, plaintext.Length);
                        blockSize = crypStream.Read(buffer, 0, maxSize);
                    }
                    return Encoding.UTF8.GetString(plaiStream.ToArray());
                }
            }

        }

 

调用结果:

 

 

标签:Convert,string,加解密,RSA,笔记,ToBase64String,-----,privateKeyParam,ToByteArrayUnsign
From: https://www.cnblogs.com/Sientuo/p/18306022

相关文章

  • 第十一天笔记(MySQL单表)
    ==========================================orderby排序(1)降序(大到小)orderbydesc案例:select*fromhzorderbyiddesc;(2)升序(小到大)asc或不写案例:select*fromhzorderbyidasc;select*fromhzorderbyid;(3)二次排序案例:select......
  • 分享Flutter 教程笔记收集整理
    01. 初学者须知02. 初识Flutter03. Flutter开发环境搭建Windows版04. 创建Flutter项目05. Flutter编写一个HelloWorld程序06. FlutterTextWidget文本组件的使用07. FlutterContainer容器组件的使用08. FlutterImage图片组件的使用09. FlutterL......
  • 计组笔记第三章——存储系统
    3.1存储系统的基本概念存储器的层次结构存储器的层次结构如下图:越靠近上层的速度越快、容量越小、价格越高。存储器有Cache-主存层和主存-辅存层。辅存中的数据要调入主存后才能被CPU访问。存储器和CPU之间的调用关系如图所示:添加Cache层是为了缓解CPU速度和主存读写速度......
  • 【播客笔记】《我们为什么会受骗》强烈建议每个女生看完这本书再去恋爱! 纵横四海
    前言这是陆爻齐收听了纵横四海的播客《我们为什么会受骗》强烈建议每个女生看完这本书再去恋爱!,做的一点笔记也就是一些内容的总结和思考理解,权当作记录罢正文被骗者与骗者有两点比较重要人往往是很感性化的,难以理性地处理每件事骗者之所以能得手,很可能是因为其自身生理......
  • MySQL 学习笔记 基础(数据模型,DDL,DML)
    数据模型 SQLSQL通用语法SQL语句可以单行或多行书写,以分号结尾。SQL语句可以使用空格/缩进来增强语句的可读性。MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。注释:·单行注释:--注释内容或#注释内容(MYSQL特有)·多行注释:/*注释......
  • HTTPS请求笔记- SSL安全通道验证问题
    一直以来,遇到的POST接口请求都是键值对的json格式,最近对接了不少公安,发现body的请求体都是直接放置字符串,虽然postman中会报红,但是仍然可请求成功using(HttpClientHandlerhandle=newHttpClientHandler())using(HttpClienthttpClient=newH......
  • 算法刷题笔记 字符串哈希(C++实现)
    文章目录题目描述基本思路实现代码题目描述给定一个长度为n的字符串,再给定m个询问,每个询问包含四个整数l1,r1,l2,r2,请你判断[l1,r1]和[l2,r2]这两个区间所包含的字符串子串是否完全相同。字符串中只包含大小写英文字母和数字。输入格式第一行包含整数n和m,表示字符......
  • 算法刷题笔记 八数码(C++实现)
    文章目录题目描述基本思路实现代码题目描述在一个3×3的网格中,1∼8这8个数字和一个x恰好不重不漏地分布在这3×3的网格中。例如:123x46758在游戏过程中,可以把x与其上、下、左、右四个方向之一的数字交换(如果存在)。我们的目的是通过交换,使得网格变为如下......
  • HTML5笔记
    HTML5什么是HTML5定义万维网的核心语言、标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次重大修改环境支持Html5的浏览器包括Firefox(火狐浏览器),IE9及其更高版本,Chrome(谷歌浏览器),Safari,Opera等;国内的傲游浏览器(Maxthon),以及基于IE或Chromium(Chrome的工程版或称......
  • [MAUI 项目实战] 笔记App(二):数据库设计
    @目录Sqlite配置创建实体笔记实体类笔记分组实体笔记片段实体笔记片段负载实体笔记片段仓库实体笔记模板(场景)实体笔记片段模板实体笔记片段模板负载实体配置EF创建映射迁移和种子数据项目地址Sqlite配置应用程序里使用Sqlite作为数据库,使用EntityFramworkCore作为ORM,使用CodeFir......