通过前面的文章我们学会了如何生成公钥和私钥,详见这篇文章:https://blog.csdn.net/yysyangyangyangshan/article/details/80368397。
那么,我们来看在C#中如何实现RSA加密解密。直接上代码,如下类是RSA算法实现的加密,加解密,签名以及签名的验证。
   /// <summary>  /// 类名:RSACrypt  /// 功能:RSA加密、解密、签名、验签  /// </summary>  public sealed class RSACrypt{/// <summary>  /// 签名  /// </summary>  /// <param name="content">待签名字符串</param>  /// <param name="privateKey">私钥</param>  /// <param name="input_charset">编码格式</param>  /// <returns>签名后字符串</returns>  public static string sign(string content, string privateKey, string input_charset){byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);SHA1 sh = new SHA1CryptoServiceProvider();byte[] signData = rsa.SignData(Data, sh);return Convert.ToBase64String(signData);}/// <summary>  /// 验签  /// </summary>  /// <param name="content">待验签字符串</param>  /// <param name="signedString">签名</param>  /// <param name="publicKey">公钥</param>  /// <param name="input_charset">编码格式</param>  /// <returns>true(通过),false(不通过)</returns>  public static bool verify(string content, string signedString, string publicKey, string input_charset){bool result = false;byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);byte[] data = Convert.FromBase64String(signedString);RSAParameters paraPub = ConvertFromPublicKey(publicKey);RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();rsaPub.ImportParameters(paraPub);SHA1 sh = new SHA1CryptoServiceProvider();result = rsaPub.VerifyData(Data, sh, data);return result;}/// <summary>  /// 加密  /// </summary>  /// <param name="resData">需要加密的字符串</param>  /// <param name="publicKey">公钥</param>  /// <param name="input_charset">编码格式</param>  /// <returns>明文</returns>  public static string encryptData(string resData, string publicKey, string input_charset){byte[] DataToEncrypt = Encoding.ASCII.GetBytes(resData);string result = encrypt(DataToEncrypt, publicKey, input_charset);return result;}/// <summary>  /// 解密  /// </summary>  /// <param name="resData">加密字符串</param>  /// <param name="privateKey">私钥</param>  /// <param name="input_charset">编码格式</param>  /// <returns>明文</returns>  public static string decryptData(string resData, string privateKey, string input_charset){byte[] DataToDecrypt = Convert.FromBase64String(resData);string result = "";for (int j = 0; j < DataToDecrypt.Length / 128; j++){byte[] buf = new byte[128];for (int i = 0; i < 128; i++){buf[i] = DataToDecrypt[i + 128 * j];}result += decrypt(buf, privateKey, input_charset);}return result;}private static string encrypt(byte[] data, string publicKey, string input_charset){RSACryptoServiceProvider rsa = DecodePemPublicKey(publicKey);SHA1 sh = new SHA1CryptoServiceProvider();byte[] result = rsa.Encrypt(data, false);return Convert.ToBase64String(result);}private static string decrypt(byte[] data, string privateKey, string input_charset){string result = "";RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);SHA1 sh = new SHA1CryptoServiceProvider();byte[] source = rsa.Decrypt(data, false);char[] asciiChars = new char[Encoding.GetEncoding(input_charset).GetCharCount(source, 0, source.Length)];Encoding.GetEncoding(input_charset).GetChars(source, 0, source.Length, asciiChars, 0);result = new string(asciiChars);return result;}private static RSACryptoServiceProvider DecodePemPublicKey(String pemstr){byte[] pkcs8publickkey;pkcs8publickkey = Convert.FromBase64String(pemstr);if (pkcs8publickkey != null){RSACryptoServiceProvider rsa = DecodeRSAPublicKey(pkcs8publickkey);return rsa;}elsereturn null;}private static RSACryptoServiceProvider DecodePemPrivateKey(String pemstr){byte[] pkcs8privatekey;pkcs8privatekey = Convert.FromBase64String(pemstr);if (pkcs8privatekey != null){RSACryptoServiceProvider rsa = DecodePrivateKeyInfo(pkcs8privatekey);return rsa;}elsereturn null;}private static RSACryptoServiceProvider DecodePrivateKeyInfo(byte[] pkcs8){byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };byte[] seq = new byte[15];MemoryStream mem = new MemoryStream(pkcs8);int lenstream = (int)mem.Length;BinaryReader binr = new BinaryReader(mem);   byte bt = 0;ushort twobytes = 0;try{twobytes = binr.ReadUInt16();if (twobytes == 0x8130)   binr.ReadByte();   else if (twobytes == 0x8230)binr.ReadInt16(); elsereturn null;bt = binr.ReadByte();if (bt != 0x02)return null;twobytes = binr.ReadUInt16();if (twobytes != 0x0001)return null;seq = binr.ReadBytes(15); if (!CompareBytearrays(seq, SeqOID)) return null;bt = binr.ReadByte();if (bt != 0x04) return null;bt = binr.ReadByte();if (bt == 0x81)binr.ReadByte();elseif (bt == 0x82)binr.ReadUInt16();byte[] rsaprivkey = binr.ReadBytes((int)(lenstream - mem.Position));RSACryptoServiceProvider rsacsp = DecodeRSAPrivateKey(rsaprivkey);return rsacsp;}catch (Exception){return null;}finally { binr.Close(); }}private static bool CompareBytearrays(byte[] a, byte[] b){if (a.Length != b.Length)return false;int i = 0;foreach (byte c in a){if (c != b[i])return false;i++;}return true;}private static RSACryptoServiceProvider DecodeRSAPublicKey(byte[] publickey){byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };byte[] seq = new byte[15];MemoryStream mem = new MemoryStream(publickey);BinaryReader binr = new BinaryReader(mem); byte bt = 0;ushort twobytes = 0;try{twobytes = binr.ReadUInt16();if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230)binr.ReadInt16(); elsereturn null;seq = binr.ReadBytes(15); if (!CompareBytearrays(seq, SeqOID)) return null;twobytes = binr.ReadUInt16();if (twobytes == 0x8103) binr.ReadByte(); else if (twobytes == 0x8203)binr.ReadInt16(); elsereturn null;bt = binr.ReadByte();if (bt != 0x00) return null;twobytes = binr.ReadUInt16();if (twobytes == 0x8130) binr.ReadByte();else if (twobytes == 0x8230)binr.ReadInt16();elsereturn null;twobytes = binr.ReadUInt16();byte lowbyte = 0x00;byte highbyte = 0x00;if (twobytes == 0x8102) lowbyte = binr.ReadByte();else if (twobytes == 0x8202){highbyte = binr.ReadByte();lowbyte = binr.ReadByte();}elsereturn null;byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; int modsize = BitConverter.ToInt32(modint, 0);byte firstbyte = binr.ReadByte();binr.BaseStream.Seek(-1, SeekOrigin.Current);if (firstbyte == 0x00){   binr.ReadByte();   modsize -= 1;  }byte[] modulus = binr.ReadBytes(modsize);  if (binr.ReadByte() != 0x02)  return null;int expbytes = (int)binr.ReadByte();   byte[] exponent = binr.ReadBytes(expbytes);RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();RSAParameters RSAKeyInfo = new RSAParameters();RSAKeyInfo.Modulus = modulus;RSAKeyInfo.Exponent = exponent;RSA.ImportParameters(RSAKeyInfo);return RSA;}catch (Exception){return null;}finally { binr.Close(); }}private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey){byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;MemoryStream mem = new MemoryStream(privkey);BinaryReader binr = new BinaryReader(mem); byte bt = 0;ushort twobytes = 0;int elems = 0;try{twobytes = binr.ReadUInt16();if (twobytes == 0x8130)  binr.ReadByte(); else if (twobytes == 0x8230)binr.ReadInt16();  elsereturn null;twobytes = binr.ReadUInt16();if (twobytes != 0x0102) return null;bt = binr.ReadByte();if (bt != 0x00)return null;elems = GetIntegerSize(binr);MODULUS = binr.ReadBytes(elems);elems = GetIntegerSize(binr);E = binr.ReadBytes(elems);elems = GetIntegerSize(binr);D = binr.ReadBytes(elems);elems = GetIntegerSize(binr);P = binr.ReadBytes(elems);elems = GetIntegerSize(binr);Q = binr.ReadBytes(elems);elems = GetIntegerSize(binr);DP = binr.ReadBytes(elems);elems = GetIntegerSize(binr);DQ = binr.ReadBytes(elems);elems = GetIntegerSize(binr);IQ = binr.ReadBytes(elems);RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();RSAParameters RSAparams = new RSAParameters();RSAparams.Modulus = MODULUS;RSAparams.Exponent = E;RSAparams.D = D;RSAparams.P = P;RSAparams.Q = Q;RSAparams.DP = DP;RSAparams.DQ = DQ;RSAparams.InverseQ = IQ;RSA.ImportParameters(RSAparams);return RSA;}catch (Exception){return null;}finally { binr.Close(); }}private static int GetIntegerSize(BinaryReader binr){byte bt = 0;byte lowbyte = 0x00;byte highbyte = 0x00;int count = 0;bt = binr.ReadByte();if (bt != 0x02) return 0;bt = binr.ReadByte();if (bt == 0x81)count = binr.ReadByte(); elseif (bt == 0x82){highbyte = binr.ReadByte(); lowbyte = binr.ReadByte();byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };count = BitConverter.ToInt32(modint, 0);}else{count = bt;  }while (binr.ReadByte() == 0x00){  count -= 1;}binr.BaseStream.Seek(-1, SeekOrigin.Current);       return count;}private static RSAParameters ConvertFromPublicKey(string pemFileConent){byte[] keyData = Convert.FromBase64String(pemFileConent);if (keyData.Length < 162){throw new ArgumentException("pem file content is incorrect.");}byte[] pemModulus = new byte[128];byte[] pemPublicExponent = new byte[3];Array.Copy(keyData, 29, pemModulus, 0, 128);Array.Copy(keyData, 159, pemPublicExponent, 0, 3);RSAParameters para = new RSAParameters();para.Modulus = pemModulus;para.Exponent = pemPublicExponent;return para;}private static RSAParameters ConvertFromPrivateKey(string pemFileConent){byte[] keyData = Convert.FromBase64String(pemFileConent);if (keyData.Length < 609){throw new ArgumentException("pem file content is incorrect.");}int index = 11;byte[] pemModulus = new byte[128];Array.Copy(keyData, index, pemModulus, 0, 128);index += 128;index += 2;byte[] pemPublicExponent = new byte[3];Array.Copy(keyData, index, pemPublicExponent, 0, 3);index += 3;index += 4;byte[] pemPrivateExponent = new byte[128];Array.Copy(keyData, index, pemPrivateExponent, 0, 128);index += 128;index += ((int)keyData[index + 1] == 64 ? 2 : 3);byte[] pemPrime1 = new byte[64];Array.Copy(keyData, index, pemPrime1, 0, 64);index += 64;index += ((int)keyData[index + 1] == 64 ? 2 : 3);//346  byte[] pemPrime2 = new byte[64];Array.Copy(keyData, index, pemPrime2, 0, 64);index += 64;index += ((int)keyData[index + 1] == 64 ? 2 : 3);byte[] pemExponent1 = new byte[64];Array.Copy(keyData, index, pemExponent1, 0, 64);index += 64;index += ((int)keyData[index + 1] == 64 ? 2 : 3);byte[] pemExponent2 = new byte[64];Array.Copy(keyData, index, pemExponent2, 0, 64);index += 64;index += ((int)keyData[index + 1] == 64 ? 2 : 3);byte[] pemCoefficient = new byte[64];Array.Copy(keyData, index, pemCoefficient, 0, 64);RSAParameters para = new RSAParameters();para.Modulus = pemModulus;para.Exponent = pemPublicExponent;para.D = pemPrivateExponent;para.P = pemPrime1;para.Q = pemPrime2;para.DP = pemExponent1;para.DQ = pemExponent2;para.InverseQ = pemCoefficient;return para;}}

测试代码如下,

    static void Main(string[] args){/**RSA加密测试,RSA中的密钥对通过SSL工具生成,生成命令如下: * 1 生成RSA私钥: * openssl genrsa -out rsa_private_key.pem 1024 *2 生成RSA公钥 * openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem * * 3 将RSA私钥转换成PKCS8格式 * openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_pub_pk8.pem * * 直接打开rsa_private_key.pem和rsa_pub_pk8.pem文件就可以获取密钥对内容,获取密钥对内容组成字符串时,注意将换行符删除 * *///rsa_pub_pk8.pem内容string privatekey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMsrofD5ET//8cozXO6RBNqj/Jt2btGltDZu8NMe0NbKzHjq8gLjCiw1nA/dubESnOrx/oHeNl6q1yjEJZ9U2LVLUU2PIqkLnnGaPOsJM1R72ZKArDKgZT+QelHgXJdOA/TZeS4Ndcms4OUNBCDRQ2uBuQD0FugvF3GRkuynW2yFAgMBAAECgYEAwlEMBOaiqfyIbCTt+Dp5UwhOvP3sBdWfZAR9jt7FTPoP0IKdT0eI3jmz9rTROlub+1XSXrGCfM6XFKVtelNzI1PqEB+QomBhZtwhzSmxrFWCg4q2oeZsqROKlDBDhV8pFhGX9Euo4HxsNJWLcA4Ngt6ZIwV/Drj7uOEA06UxFyECQQD76Fl4rKPOdzC0RBtRZEqxmC32nikwAWz2FqinNzee+tiMeF2OydP1bCTp3R/mo6Li7hqUcV3LjFCf4nFB8K5ZAkEAzniXc7ppAL286XtKlIOVQnxlhL+wDGtbHZ+SppD02OBFoDGPOivYz8yKL7ktgFwfGzRhGKjJXuXgHwmCnvjiDQJAFhgG4OKja1Rg3S6sBrN5KaJjRaIRkrhNSjgqip/5LORrYcaczg09neTiR/Cw/5WSj7y6cBKRW2zvFVbTACmP4QJATgVZzdyKI0KPqXbyhs52T6psPk6lOvwycS5En3a1X2LYTKGNqwC4rEVxjnkeTZwCESio7EWT2q1pFLFmT6Zi3QJBAKwE1Q3l20UikKhDNrAhxv1R3GgLf8d++Oz5nsQL1yL/blwn3/Bm5Zr+S1XYH5Sz7TBitilmFuO2Wy3xI26EQcQ=";//rsa_public_key.pem内容string publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLK6Hw+RE///HKM1zukQTao/ybdm7RpbQ2bvDTHtDWysx46vIC4wosNZwP3bmxEpzq8f6B3jZeqtcoxCWfVNi1S1FNjyKpC55xmjzrCTNUe9mSgKwyoGU/kHpR4FyXTgP02XkuDXXJrODlDQQg0UNrgbkA9BboLxdxkZLsp1tshQIDAQAB";//加密字符串  string data = "yangyoushan";Console.WriteLine("加密前字符串内容:" + data);//加密  string encrypteddata = RSACrypt.encryptData(data, publickey, "UTF-8");Console.WriteLine("加密后的字符串为:" + encrypteddata);Console.WriteLine("解密后的字符串内容:" + RSACrypt.decryptData(encrypteddata, privatekey, "UTF-8"));Console.WriteLine("*****我是分割线******");//解密  string endata = "VbOtmCuc8+8gKXbDyYHAVG6Hnoa7lCphMZePUmxaM7zQ0XD7oTcRY59xNo9xOpwG5YwjbEiHKcuANuKNBlPLkieX5yGSS8iOd1cki+DujqUtffHQicMegubh4vaPhvhBnOflUejtZH1xi2r2a2t8v9xQO+vmZc7gNJ91+3gtFuc=";string datamw = RSACrypt.decryptData(endata, privatekey, "UTF-8");Console.WriteLine("静态加密后的字符串为:" + endata);Console.WriteLine("解密后的字符串内容:" + datamw);//签名  string signdata = "20180522201658IMFINE";Console.WriteLine("签名前的字符串内容:" + signdata);string sign = RSACrypt.sign(signdata, privatekey, "UTF-8");Console.WriteLine("签名后的字符串:" + sign);string sourceSign = "VEAgvbHavdbOPYSP8jqxJPYTv/FV/Nl3MClHFBN4qvDRM3ixbOKpUY2P1w99edC29C4Q7qNY99jKYJucRM21mBf8RgEnsBqZVIzqnJYafIQ0AFCL7BpNAORM7uns+NxFj2Zse6Kr61lSpEvie1GCzo+iuYYvzPlMlz+W6nScp2A=";Console.WriteLine("生成的签名:" + sourceSign);bool realSign1 = RSACrypt.verify("20180522201658IMFINE", sign, publickey, "UTF-8");Console.WriteLine(realSign1);bool realSign2 = RSACrypt.verify("20180522201658IMFINEHAHA", sign, publickey, "UTF-8");Console.WriteLine(realSign2);Console.ReadLine();  }

执行结果如下,

除了算法比较复杂,代码逻辑并无复杂的地方,大家自行下载代码运行即可。

安全不安全002:C#实现RSA算法加密解密相关推荐

  1. RSA算法加密解密举例

    RSA算法加密解密举例 使用如下数字字母对照表: 明文M="its all greek to me" ,p=47,q=59,e=17,求出其密文以及给出RSA 算法加/解密过程.( ...

  2. .NET Core 使用RSA算法 加密/解密/签名/验证签名

    前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...

  3. JAVA RSA算法加密实现 eclipse

    RSA算法加密实现 一.实验目的 学习经典的RSA公钥加密算法的基本原理和特点,能够编写简单的代码实现RSA公钥加密和私钥解密的过程. 二.实验要求 1. 熟悉RSA公私钥加密算法. 2. 掌握如何使 ...

  4. 用RSA算法加密文本文件

    用RSA算法加密文本文件 写文目的 任务说明 代码实现 (1)RSA加密比较小的txt文件 (2)生成1M和1G的txt文件 (3)加密1M的txt文件 调试过程 写文目的 当时参照网上其他文章写的, ...

  5. RSA算法加解密的C语言实现

    RSA算法加解密的C语言实现 一. 实现的功能 二. 源代码 一. 实现的功能 用户输入明文 自动随机生成较大的数p和q,并对它们进行素性检测,检测成功之后,程序继续 计算Φ(n)的值,并求出它的所有 ...

  6. RSA算法加密Web页面密码提交和验证实测

    理论可以参考百度:关于加密解密过程降解,觉得比较好的:一篇博文 因客户要求把web页面提交/验证改用RSA算法加密密文传递到后台: 1,js/jsp客户端部分RSA加密密码: 2,服务端Java解密: ...

  7. Android-RSA算法加密解密

    被这个小问题困了2天,终于被干掉了. 安卓中利用RSA算法加密和解密 整个流程大致为:生成密钥对->获取公私钥->对明(密)文加(解)密. package com.cc.encryptte ...

  8. 加密解密_使用RSA密钥对加密解密数据

    使用RSA密钥对加密解密数据 作者: 郭政鸿 2021/1/6 前言: 前几天看了非对称加密, 那非对称加密处理常见的https中的应用, 平时我们可以用来做什么呢? 1. 生成RSA密钥对 使用op ...

  9. java rsa 117_java实现RSA非对称加密解密

    之前写过一篇java实现AES对称加密解密 在对密码加密传输的场景下 RSA非对称加密解密可能会更加适合. 原理就是后台生成一对公钥和私钥,公钥给前端用来加密,后台用私钥去解密,保证了传输过程中就算被 ...

最新文章

  1. java 创建5个线程_Java创建线程的三种方式
  2. [LeetCode]: 53: Maximum Subarray
  3. web项目没有run on server时..
  4. 2015大学计算机基础,2015新生入学大学计算机基础复习资料
  5. [tp3.2.1]数据模型 - 简单的模型连接
  6. 特斯拉市值超过波音 成美国市值最高工业公司
  7. Lenovo ThinkPad T系列解决 VMware Workstation 打开虚拟机提示:Intel VT-x处于禁用状态问题
  8. C++类的静态成员变量
  9. Linux安装后无法进入图形界面(GNOME,KDE等)的解决方法
  10. easyui 动态添加标签页,总结
  11. 网页素材精品:一组五彩缤纷的免费矢量背景素材
  12. 如何解决下载慢的大问题,如neo4j等
  13. 车间和仓库可以一起吗_车间和仓库可以划分为一个防火分区吗
  14. 张志华 统计机器学习
  15. ecmall购物获积分功能 积分抵扣设置 积分购物
  16. vue改变class内的属性_vue 绑定 添加class 属性 4种方法 添加style 3中方法 v-bind /:...
  17. 怎么做GIF动画?怎样将图片合成gif动图
  18. aso优化重要ASO优化技巧大全,ASO标题优化技巧:实战案例解析
  19. 【优雅编程之道】之数组的7点建议
  20. Android之更换头像

热门文章

  1. Python实战,爬取金融期货数据
  2. 为什么说Objective-C是一门动态的语言?
  3. Quartus II自带仿真工具的使用
  4. Windows —— SMTP服务器
  5. “全国普通高校大学生竞赛榜单”比赛的官网地址(2023.1.14更新)
  6. 欧几里德和扩展欧几里德算法
  7. Python 实现快递物流信息查询
  8. 关于js中window.location.href、location.href重定向
  9. 成享汇:互联网资深赚客为您分享如何找到合适自己的道路
  10. .NET Compact Framework下的串口通信