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);
            }
        }
    }
    

    }


  • 相关阅读:
    LeetCode 230. Kth Smallest Element in a BST
    LeetCode 114. Flatten Binary Tree to Linked List
    LeetCode 222. Count Complete Tree Nodes
    LeetCode 129. Sum Root to Leaf Numbers
    LeetCode 113. Path Sum II
    LeetCode 257. Binary Tree Paths
    Java Convert String & Int
    Java Annotations
    LeetCode 236. Lowest Common Ancestor of a Binary Tree
    LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/Laggage/p/11028614.html
Copyright © 2011-2022 走看看