基于私钥加密公钥解密的RSA算法C#实现方法

作者:shichen2014 时间:2022-12-01 07:52:37 

本文实例讲述了基于私钥加密公钥解密的RSA算法C#实现方法,是一种应用十分广泛的算法。分享给大家供大家参考之用。具体方法如下:

一、概述

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。
RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。
密钥对的产生。选择两个大素数,p 和q 。计算:
  n = p * q
然后随机选择加密密钥e(PS:最常用的e值有3,17和65537,微软就是使用的65537,采用3个中的任何一个都不存在安全问题),要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用Euclid 算法计算解密密钥d, 满足
  e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )
其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。
加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 ,m2,..., mi ,块长s,其中 2^s <= n, s 尽可能的大。对应的密文是:
        ci = mi^e ( mod n ) ( a )
解密时作如下计算:
        mi = ci^d ( mod n ) ( b )

.NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,但导出的私钥包含上面8个属性,显然要用RSACryptoServiceProvider实现私钥加密公钥是不可行的。

从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

二、实现方法

本人利用网上找的一个C#版的大整数类BigInteger(本人认为这是偶发现的效率最高的一个C#版大整数类)来实现私钥加密公钥加密(事实上也完全支持公租加密私钥解密),但没有使用类BigInteger的大素数生成函数,而是直接使用类RSACryptoServiceProvider来生成大素数。其中加密函数和解密函数的实现如下:


/*
功能:用指定的私钥(n,d)加密指定字符串source
*/
private string EncryptString(string source, BigInteger d, BigInteger n)
{
int len = source.Length;
int len1 = 0;
int blockLen = 0;
if ((len % 128) == 0)
len1 = len / 128;
else
len1 = len / 128 + 1;
string block = "";
string temp = "";
for (int i = 0; i < len1; i++)
{
if (len >= 128)
 blockLen = 128;
else
 blockLen = len;
block = source.Substring(i * 128, blockLen);
byte[] oText = System.Text.Encoding.Default.GetBytes(block);
BigInteger biText = new BigInteger(oText);
BigInteger biEnText = biText.modPow(d, n);
string temp1 = biEnText.ToHexString();
temp += temp1;
len -= blockLen;
}
return temp;
}
/*
功能:用指定的公钥(n,e)解密指定字符串source
*/
private string DecryptString(string source, BigInteger e, BigInteger n)
{
int len = source.Length;
int len1 = 0;
int blockLen = 0;
if ((len % 256) == 0)
len1 = len / 256;
else
len1 = len / 256 + 1;
string block = "";
string temp = "";
for (int i = 0; i < len1; i++)
{
if (len >= 256)
 blockLen = 256;
else
 blockLen = len;
block = source.Substring(i * 256, blockLen);
BigInteger biText = new BigInteger(block, 16);
BigInteger biEnText = biText.modPow(e, n);
string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes());
temp += temp1;
len -= blockLen;
}
return temp;
}

加密过程和解密过程代码如下所示:


/*
加密过程,其中d、n是RSACryptoServiceProvider生成的D、Modulus
*/
private string EncryptProcess(string source, string d, string n)
{
byte[] N = Convert.FromBase64String(n);
byte[] D = Convert.FromBase64String(d);
BigInteger biN = new BigInteger(N);
BigInteger biD = new BigInteger(D);
return EncryptString(source, biD, biN);
}

/*
解密过程,其中e、n是RSACryptoServiceProvider生成的Exponent、Modulus
*/
private string DecryptProcess(string source, string e, string n)
{
byte[] N = Convert.FromBase64String(n);
byte[] E = Convert.FromBase64String(e);
BigInteger biN = new BigInteger(N);
BigInteger biE = new BigInteger(E);
return DecryptString(source, biE, biN);
}

相信本文所述对大家的C#程序设计有一定的借鉴价值。

标签:RSA,算法,C#
0
投稿

猜你喜欢

  • C#多线程中的异常处理操作示例

    2023-07-16 06:10:10
  • Android 关机弹出选择菜单的深入解析

    2023-03-19 20:56:09
  • Android 文件存储及常见问题解决

    2023-07-12 13:25:45
  • 如何实现bean初始化摧毁方法的注入

    2023-07-22 05:14:31
  • Java泛型之类型擦除实例详解

    2022-02-13 06:39:36
  • 基于SpringBoot中activeMq的JmsTemplate的实例

    2021-11-04 15:36:34
  • Android加载Assets目录中Xml布局文件

    2021-06-19 14:59:53
  • IDEA 2020.1 版自动导入MAVEN依赖的方法(新版MAVEN无法自动导入/更新POM依赖、MAVEN设置自动更新、自动更新快捷键)

    2022-08-27 09:31:22
  • Java concurrency集合之 CopyOnWriteArrayList_动力节点Java学院整理

    2022-10-27 05:03:36
  • C#使用oledb操作excel文件的方法

    2023-06-13 19:19:42
  • Mybatis-Plus的SQL语句组拼原理说明

    2021-07-03 20:39:22
  • java LRU(Least Recently Used )详解及实例代码

    2022-10-08 10:42:43
  • Java中常见的对象转换工具

    2023-12-14 19:23:16
  • 深入理解C++中public、protected及private用法

    2023-07-02 11:30:17
  • java实现Dijkstra最短路径算法

    2022-11-30 21:02:15
  • java_object的简单使用详解

    2023-08-22 11:35:57
  • Android Studio多渠道打包的配置方法

    2023-06-15 23:19:48
  • java实现http的Post、Get、代理访问请求

    2021-10-30 08:13:47
  • mybatis的动态SQL和模糊查询实例详解

    2022-03-10 09:47:03
  • Android Handler,Message,MessageQueue,Loper源码解析详解

    2022-04-17 17:34:57
  • asp之家 软件编程 m.aspxhome.com