• C#实现RSA加密解密


    RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。
    RSA的缺点:

      • 产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。

      • 分组长度太大,为保证安全性,n 至少也要 600bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。目前,SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。C)RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。

    保密级别对称密钥长度(bit)RSA密钥长度(bit)ECC密钥长度(bit)保密年限
    80 80 1024 160 2010
    112 112 2048 224 2030
    128 128 3072 256 2040
    192 192 7680 384 2080
    256 256 15360 512 2120

    C#中RSA的相关操作

    • 生成公钥和私钥
      public class RSASecretKey
          {
              public RSASecretKey() { }
              public RSASecretKey(string privateKey, string publicKey)
              {
                  PrivateKey = privateKey;
                  PublicKey = publicKey;
              }
              public string PublicKey { get; set; }
              public string PrivateKey { get; set; }
              public override string ToString()
              {
                  return string.Format(
                      "PrivateKey: {0}
      PublicKey: {1}", PrivateKey, PublicKey);
              }
      
              /// <summary>
              /// 生成公钥私钥
              /// </summary>
              /// <param name="keySize">the size of the key,must from 384 bits to 16384 bits in increments of 8 </param>
              /// <returns></returns>
              public RSASecretKey GenerateRSASecretKey(int keySize)
              {
                  RSASecretKey rsaKey = new RSASecretKey();
                  using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize))
                  {
                      rsaKey.PrivateKey = rsa.ToXmlString(true);
                      rsaKey.PublicKey = rsa.ToXmlString(false);
                  }
                  return rsaKey;
              }
              
          }

    • 实现公钥加密私钥解密
          public class RSAHelper
          {
              /// <summary>
              /// 加密
              /// </summary>
              /// <param name="xmlPublicKey"></param>
              /// <param name="content"></param>
              /// <returns></returns>
              public string RSAEncrypt(string xmlPublicKey, string content)
              {
                  string encryptedContent = string.Empty;
                  using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      rsa.FromXmlString(xmlPublicKey);
                      byte[] encryptedData = rsa.Encrypt(Encoding.Default.GetBytes(content), false);
                      encryptedContent = Convert.ToBase64String(encryptedData);
                  }
                  return encryptedContent;
              }
              /// <summary>
              /// 解密
              /// </summary>
              /// <param name="xmlPrivateKey"></param>
              /// <param name="content"></param>
              /// <returns></returns>
              public string RSADecrypt(string xmlPrivateKey, string content)
              {
                  string decryptedContent = string.Empty;
                  using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      rsa.FromXmlString(xmlPrivateKey);
                      byte[] decryptedData = rsa.Decrypt(Convert.FromBase64String(content), false);
                      decryptedContent = Encoding.GetEncoding("gb2312").GetString(decryptedData);
                  }
                  return decryptedContent;
              }
      
      
          }

      密钥格式的转换

      C#中RSA公钥和私钥的格式都是XML的,而在其他语言如java中,生成的RSA密钥就是普通的Base64字符串,所以需要将C#xml格式的密钥转换成普通的Base64字符串,同时也要实现Base64密钥字符串生成C#中xml格式的密钥.
      安装 BouncyCastle 这个Nuget包
      PM > Install-Package BouncyCastle
      BouncyCastle项目网址
      BouncyCastlegithub地址
      构造一个RSAKeyConventer类

          using System;
          using System.Security.Cryptography;
          using Org.BouncyCastle.Asn1.Pkcs;
          using Org.BouncyCastle.Math;
          using Org.BouncyCastle.Pkcs;
          using Org.BouncyCastle.Asn1.X509;
          using Org.BouncyCastle.X509;
          using Org.BouncyCastle.Security;
          using Org.BouncyCastle.Crypto.Parameters;
      
          public class RSAKeyConverter
          {
              /// <summary>
              /// xml private key -> base64 private key string
              /// </summary>
              /// <param name="xmlPrivateKey"></param>
              /// <returns></returns>
              public static string FromXmlPrivateKey(string xmlPrivateKey)
              {
                  string result = string.Empty;
                  using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      rsa.FromXmlString(xmlPrivateKey);
                      RSAParameters param = rsa.ExportParameters(true);
                      RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(
                          new BigInteger(1, param.Modulus), new BigInteger(1, param.Exponent),
                          new BigInteger(1, param.D), new BigInteger(1, param.P),
                          new BigInteger(1, param.Q), new BigInteger(1, param.DP),
                          new BigInteger(1, param.DQ), new BigInteger(1, param.InverseQ));
                      PrivateKeyInfo privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
                     
                      result = Convert.ToBase64String(privateKey.ToAsn1Object().GetEncoded());
                  }
                  return result;
              }
      
              /// <summary>
              /// xml public key -> base64 public key string
              /// </summary>
              /// <param name="xmlPublicKey"></param>
              /// <returns></returns>
              public static string FromXmlPublicKey(string xmlPublicKey)
              {
                  string result = string.Empty;
                  using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      rsa.FromXmlString(xmlPublicKey);
                      RSAParameters p = rsa.ExportParameters(false);
                      RsaKeyParameters keyParams = new RsaKeyParameters(
                          false, new BigInteger(1,p.Modulus), new BigInteger(1, p.Exponent));
                      SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyParams);
                      result = Convert.ToBase64String(publicKeyInfo.ToAsn1Object().GetEncoded());
                  }
                  return result;
              }
      
              /// <summary>
              /// base64 private key string -> xml private key
              /// </summary>
              /// <param name="privateKey"></param>
              /// <returns></returns>
              public static string ToXmlPrivateKey(string privateKey)
              {
                  RsaPrivateCrtKeyParameters privateKeyParams =
                      PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)) as RsaPrivateCrtKeyParameters;
                  using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      RSAParameters rsaParams = new RSAParameters()
                      {
                          Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned(),
                          Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned(),
                          D = privateKeyParams.Exponent.ToByteArrayUnsigned(),
                          DP = privateKeyParams.DP.ToByteArrayUnsigned(),
                          DQ = privateKeyParams.DQ.ToByteArrayUnsigned(),
                          P = privateKeyParams.P.ToByteArrayUnsigned(),
                          Q = privateKeyParams.Q.ToByteArrayUnsigned(),
                          InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned()
                      };
                      rsa.ImportParameters(rsaParams);
                      return rsa.ToXmlString(true);
                  }
              }
      
              /// <summary>
              /// base64 public key string -> xml public key
              /// </summary>
              /// <param name="pubilcKey"></param>
              /// <returns></returns>
              public static string ToXmlPublicKey(string pubilcKey)
              {
                  RsaKeyParameters p = 
                      PublicKeyFactory.CreateKey(Convert.FromBase64String(pubilcKey)) as RsaKeyParameters;
                  using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                  {
                      RSAParameters rsaParams = new RSAParameters
                      {
                          Modulus = p.Modulus.ToByteArrayUnsigned(),
                          Exponent = p.Exponent.ToByteArrayUnsigned()
                      };
                      rsa.ImportParameters(rsaParams);
                      return rsa.ToXmlString(false);
                  }
              }
          }
  • 相关阅读:
    mac下用xattr命令来删除文件的扩展属性
    使用vue.js实现checkbox的全选和多个的删除功能
    正则表达式匹配任意字符(包括换行符)的写法
    jQuery Mobile动态刷新页面样式
    jquery mobile各类标签的refresh
    jQuery .attr()和.removeAttr()方法操作元素属性示例
    jquery mobile各类组件刷新方法
    Apache PDFbox开发指南之PDF文档读取
    日期字符串解析--SimpleDateFormat严格限制日期转换setLenient(false)
    hdu5032 Always Cook Mushroom
  • 原文地址:https://www.cnblogs.com/caiyt/p/12088745.html
Copyright © 2020-2023  润新知