C# 中使用 RSA加解密算法

简介: 一、什么是RSA   RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。      在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。

一、什么是RSA

  RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。   

  在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法 与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的 密钥解密并可核对信息摘要。   

  RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

二、RSA算法密钥长度的选择

1. 非对称加密算法中1024 bit密钥的强度相当于对称加密算法80bit密钥的强度。

2. 密钥长度增长一倍,公钥操作所需时间增加约4倍,私钥操作所需时间增加约8倍,公私钥生成时间约增长16倍。

3. 一次能加密的密文长度与密钥长度成正比,加密后的密文长度跟密钥长度相同(RSA加密内容的长度有限制,和密钥长度有关,这是由它的算法决定的)

  a、加密的明文长度不能超过RSA密钥的长度减去11byte,比如密钥长度是1024位的,1024位=1024bit=128byte,128-11=117byte,所以明文长度不能超过117byte,如果长度超过该值将会抛出异常。

  b、加密后密文的长度为密钥的长度,如密钥长度为1024bit(128Byte),最后生成的密文固定为 1024bit(128Byte)。

三、C#中的RSA加解密

   .NET Framework 类库提供了System.Security 命名空间,System.Security 命名空间提供公共语言运行时安全系统的基础结构,包括权限的基类,而该命名空间下提供了RSACryptoServiceProvider类执行RSA算法的不对称加密和解密。

1.密钥对的生成:

a、根据RSACryptoServiceProvider直接生成

复制代码
/// <summary>
/// 生成密钥
/// </summary>
public RSAKey GenerateRSAKey()
{
    RSAKey RSAKEY = new RSAKey();
    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
    RSAKEY.PrivateKey = RSA.ToXmlString(true);    //生成私钥
    RSAKEY.PublicKey = RSA.ToXmlString(false);    //生成公钥
    RSA.Clear();
    return RSAKEY;
}
复制代码

b、通过Makecert证书创建工具生成安全证书

makecert -r -pe -n "CN=RSAKey" -b 03/31/2005 -e 12/31/2012 -sky exchange -ss my

可通过"Visual Studio命令提示行"执行以上命令生成证书。

查看生成的证书:

运行->输入mmc打开控制台->选择文件->添加/删除管理单元->在弹出框左侧找到证书->选中证书添加->选择我的用户账户->完成确定

此时就可以在对应位置查看到我们刚刚创建的名为RSAKey的证书了,如下图:

最终我们可以将证书导出为:

 

其中RSAKey.cer中含有加密用的公钥,RSAKey.pfx中含有解密用的私钥。

2.创建加解密RSA

复制代码
/// <summary>
/// 创建加密RSA
/// </summary>
/// <param name="publicKey">公钥</param>
/// <returns></returns>
private RSACryptoServiceProvider CreateEncryptRSA(string publicKey)
{
    try
    {
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSA.FromXmlString(publicKey);
        return RSA;
    }
    catch (CryptographicException ex)
    {
        throw ex;
    }
}

/// <summary>
/// 创建解密RSA
/// </summary>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
private RSACryptoServiceProvider CreateDecryptRSA(string privateKey)
{
    try
    {
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSA.FromXmlString(privateKey);
        return RSA;
    }
    catch (CryptographicException ex)
    {
        throw ex;
    }
}

/// <summary>
/// 根据安全证书创建加密RSA
/// </summary>
/// <param name="certfile">公钥文件</param>
/// <returns></returns>
private RSACryptoServiceProvider X509CertCreateEncryptRSA(string certfile)
{
    try
    {
        X509Certificate2 x509Cert = new X509Certificate2(certfile);
        RSACryptoServiceProvider RSA = (RSACryptoServiceProvider)x509Cert.PublicKey.Key;
        return RSA;
    }
    catch (CryptographicException ex)
    {
        throw ex;
    }
}

/// <summary>
/// 根据私钥文件创建解密RSA
/// </summary>
/// <param name="keyfile">私钥文件</param>
/// <param name="password">访问含私钥文件的密码</param>
/// <returns></returns>
private RSACryptoServiceProvider X509CertCreateDecryptRSA(string keyfile, string password)
{
    try
    {
        X509Certificate2 x509Cert = new X509Certificate2(keyfile, password);
        RSACryptoServiceProvider RSA = (RSACryptoServiceProvider)x509Cert.PrivateKey;
        return RSA;
    }
    catch (CryptographicException ex)
    {
        throw ex;
    }
}
复制代码

其中所提及的私钥文件和公钥文件就是根据Makecert证书创建工具生成安全证书,而X509CertCreateDecryptRSA方法中的参数password是我们导出私钥文件所设置的访问密码,如果没有改密码即使有私钥证书也没办法解密。

3.RSA加解密

复制代码
/// <summary>
/// 加密
/// </summary>
/// <param name="dataToEncrypt">待加密数据</param>
/// <param name="publicKey">公钥</param>
/// <returns></returns>
public string Encrypt(string dataToEncrypt, string publicKey)
{
    Encoding encoder = Encoding.UTF8;
    byte[] _dataToEncrypt = encoder.GetBytes(dataToEncrypt);
    return this.Encrypt(_dataToEncrypt, publicKey);
}

/// <summary>
/// 加密
/// </summary>
/// <param name="dataToEncrypt">待加密数据</param>
/// <param name="publicKey">公钥</param>
/// <returns></returns>
public string Encrypt(byte[] dataToEncrypt, string publicKey)
{
    using (RSACryptoServiceProvider RSA = this.CreateEncryptRSA(publicKey))
    {
        byte[] encryptedData = RSA.Encrypt(dataToEncrypt, false);
        return this.BytesToHexString(encryptedData);
    }
}

/// <summary>
/// 根据安全证书加密
/// </summary>
/// <param name="dataToEncrypt"></param>
/// <param name="certfile"></param>
/// <returns></returns>
public string X509CertEncrypt(string dataToEncrypt, string certfile)
{
    Encoding encoder = Encoding.UTF8;
    byte[] _dataToEncrypt = encoder.GetBytes(dataToEncrypt);
    return this.X509CertEncrypt(_dataToEncrypt, certfile);
}

/// <summary>
/// 根据安全证书加密
/// </summary>
/// <param name="dataToEncrypt">待加密数据</param>
/// <param name="certfile">安全证书</param>
/// <returns></returns>
public string X509CertEncrypt(byte[] dataToEncrypt, string certfile)
{
    if (!File.Exists(certfile))
    {
        throw new ArgumentNullException(certfile, "加密证书未找到");
    }
    using (RSACryptoServiceProvider RSA = this.X509CertCreateEncryptRSA(certfile))
    {
        byte[] encryptedData = RSA.Encrypt(dataToEncrypt, false);
        return this.BytesToHexString(encryptedData);
    }
}


/// <summary>
/// 解密
/// </summary>
/// <param name="encryptedData">待解密数据</param>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public string Decrypt(string encryptedData, string privateKey)
{
    using (RSACryptoServiceProvider RSA = this.CreateDecryptRSA(privateKey))
    {
        Encoding encoder = Encoding.UTF8;
        byte[] _encryptedData = HexStringToBytes(encryptedData);
        byte[] decryptedData = RSA.Decrypt(_encryptedData, false);
        return encoder.GetString(decryptedData);
    }
}

/// <summary>
/// 解密
/// </summary>
/// <param name="encryptedData">待解密数据</param>
/// <param name="keyfile">私钥文件</param>
/// <param name="password">访问私钥文件密码</param>
/// <returns></returns>
public string X509CertDecrypt(string encryptedData, string keyfile, string password)
{
    if (!File.Exists(keyfile))
    {
        throw new ArgumentNullException(keyfile, "解密证书未找到");
    }
    using (RSACryptoServiceProvider RSA = this.X509CertCreateDecryptRSA(keyfile, password))
    {
        Encoding encoder = Encoding.UTF8;
        byte[] _encryptedData = HexStringToBytes(encryptedData);
        byte[] decryptedData = RSA.Decrypt(_encryptedData, false);
        return encoder.GetString(decryptedData);
    }
}
复制代码

最后整理了一个简单的Demo:

Demo下载:RSACrypto.rar

 

参考资料:

http://dustin.iteye.com/blog/763931

http://baike.baidu.com/view/539299.htm

http://www.cnblogs.com/yjmyzz/archive/2008/08/20/1272098.html

相关文章
|
23天前
|
算法 Serverless 数据安全/隐私保护
RSA算法中,为什么需要的是两个素数?
PrimiHub是密码学专家团队开发的开源隐私计算平台,关注数据安全、密码学等领域。RSA算法使用两个素数确保安全,因为它们的乘积易于计算,但分解困难,形成加密基础。算法涉及选择大素数、计算乘积、生成公私钥对。加密时,消息通过公钥变形;解密则需私钥,安全性依赖于大数分解问题的复杂性。
|
26天前
|
算法 安全 Java
深入解析ECC(椭圆曲线密码学)加解密算法
深入解析ECC(椭圆曲线密码学)加解密算法
深入解析ECC(椭圆曲线密码学)加解密算法
|
17天前
|
Dart 算法 JavaScript
C#数据结构与算法入门教程,值得收藏学习!
C#数据结构与算法入门教程,值得收藏学习!
|
17天前
|
机器学习/深度学习 算法 搜索推荐
一个开源且全面的C#算法实战教程
一个开源且全面的C#算法实战教程
|
1月前
|
存储 编解码 算法
C#.NET逃逸时间算法生成分形图像的毕业设计完成!晒晒功能
该文介绍了一个使用C#.NET Visual Studio 2008开发的程序,包含错误修复的Julia、Mandelbrot和优化过的Newton三种算法,生成色彩丰富的分形图像。作者改进了原始算法的效率,将内层循环的画点操作移至外部,提升性能。程序提供五种图形模式,支持放大缩小及颜色更新,并允许用户自定义画布大小以调整精度。还具备保存为高质JPG的功能。附有四张示例图片展示生成的分形效果。
418 3
|
20天前
|
算法 安全 网络安全
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
支付系统,网络安全06----支付安全---,机密性,加密算法,目前最流行的加密算法,AES加密算法,目前最流行的非对称加密算法RSA,对称加密和非对称加密的优缺点,非对称加密是基于非常复杂的数学算法
|
26天前
|
存储 算法 安全
深入解析RSA算法原理及其安全性机制
深入解析RSA算法原理及其安全性机制
|
26天前
|
算法 安全 Java
AES加解密算法:原理、应用与安全性解析
AES加解密算法:原理、应用与安全性解析
|
26天前
|
Java BI C#
技术笔记:SM4加密算法实现Java和C#相互加密解密
技术笔记:SM4加密算法实现Java和C#相互加密解密
17 0
|
27天前
|
存储 安全 算法
RSA非对称加密算法中的密钥对生成与传输
RSA非对称加密算法的密钥对生成与传输是信息安全领域的核心问题之一。密钥生成过程需要保证随机性和安全性,而密钥的传输则需要选择适当的方式来确保其保密性和完整性。通过合理的密钥管理和保护措施,可以有效地利用RSA算法保护通信安全,防止信息泄露和篡改。在实际应用中,用户和系统管理员需要结合具体情况选择最佳的密钥生成和传输策略,以达到最佳的安全性和效率。

热门文章

最新文章