首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[C#]C#实现RSA加密解密

[C#]C#实现RSA加密解密

作者头像
云未归来
发布2025-07-20 18:35:53
发布2025-07-20 18:35:53
26500
代码可运行
举报
运行总次数:0
代码可运行

RSA介绍

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

RSA的缺点:

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

RSA的参数

RSA密码由三个整数组成,我们分别称之为n, e, d

(n、d): 私钥,这个我们要私密保存 (n、e): 公钥,可以对外公布 n: 模数(Modulus),私钥和公钥都包含有这个数 e: 公钥指数(publicExponent),一般是固定值65537 d私钥指数(privateExponent)

dotnet中的表示RSA参数的结构体是RSAParameters

image
image

openssl生成RSA密钥对

1. 生成一个RSA密钥

openssl genrsa -out private_pkcs1.pem 2048

上面的命令导出是pkcs#1格式rsa私钥

2. 从生成的RSA密钥中提取RSA公钥

ps: 私钥中包含了公钥相关信息,所以可以从私钥中导出公钥信息

openssl rsa -in private_pkcs1.pem -out public_pkcs1.pem -pubout -RSAPublicKey_out

公钥格式转换(PKCS#8 => PKCS#1)

openssl rsa -in public_pkcs8.pem -out public_pkcs1.pem -pubin -RSAPublicKey_out

私钥格式转换 (PKCS#1 => PKCS#8)

openssl pkcs8 -in private_pkcs1.pem -out private_pkcs8.pem -topk8 -nocrypt

RSA私钥格式转换(PKCS#8 => PKCS#1)

openssl rsa -in private_pkcs8.pem -out private_pkcs1.pem

C#中RSA的相关操作

生成公钥和私钥

代码语言:javascript
代码运行次数:0
运行
复制
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;
}

实现公钥加密私钥解密

代码语言:javascript
代码运行次数:0
运行
复制
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

代码语言:javascript
代码运行次数:0
运行
复制
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
    {
        /// <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);
            }
        }
    }
}

C# 折叠 复制 全屏

js的rsa操作

移步: GitHub - travist/jsencrypt: A zero-dependency Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation.

作者:Laggage

出处:https://www.cnblogs.com/laggage/p/11028614.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RSA介绍
  • RSA的参数
  • openssl生成RSA密钥对
    • 1. 生成一个RSA密钥
    • 2. 从生成的RSA密钥中提取RSA公钥
    • 公钥格式转换(PKCS#8 => PKCS#1)
    • 私钥格式转换 (PKCS#1 => PKCS#8)
    • RSA私钥格式转换(PKCS#8 => PKCS#1)
  • C#中RSA的相关操作
    • 密钥格式的转换
  • js的rsa操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档