zoukankan      html  css  js  c++  java
  • C#实现RSA加密解密

    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的相关操作

    • 生成公钥和私钥
    struct 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>
    /// generate RSA secret key
    /// </summary>
    /// <param name="keySize">the size of the key,must from 384 bits to 16384 bits in increments of 8 </param>
    /// <returns></returns>
    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;
    }

    • 实现公钥加密私钥解密
    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;
    }
    

    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

    namespace RSA
    {
        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
    {
        /// &lt;summary&gt;
        /// xml private key -&gt; base64 private key string
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;xmlPrivateKey&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        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;
        }
    
        /// &lt;summary&gt;
        /// xml public key -&gt; base64 public key string
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;xmlPublicKey&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        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;
        }
    
        /// &lt;summary&gt;
        /// base64 private key string -&gt; xml private key
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;privateKey&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        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);
            }
        }
    
        /// &lt;summary&gt;
        /// base64 public key string -&gt; xml public key
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;pubilcKey&quot;&gt;&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        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);
            }
        }
    }
    

    }


  • 相关阅读:
    nignx 配置https
    开发插件
    pdf 转word 网站
    github 镜像站点
    apk 托管
    系统引导原理以及过程
    网络维护-路由与路由的链接
    linux 常用命令
    Linux netsat 命令
    Oracle登录 ORA-01033: ORACLE正在初始化或关闭的解决方法
  • 原文地址:https://www.cnblogs.com/Laggage/p/11028614.html
Copyright © 2011-2022 走看看