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}\r\nPublicKey: {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);
        }
    }
}

}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM