日期:2013-02-26  浏览次数:20555 次

实际没做什么事情,想起来也无耻,不过可能有些朋友比较懒的话,也会有一点用的。在此先向 duduwolf 表示歉意再说。

嘟嘟狼的原文如下:http://dev.csdn.net/develop/article/30/30182.shtm

我的无耻成果如下(有些地方作了一些小调整):

#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

#endregion

namespace rsatest
{

/*
??? RSA算法
????? 1978年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法。
??? 它易于理解和操作,也很流行。算法的名字以发明者的名字命名:Ron Rivest,
??? AdiShamir 和Leonard Adleman。但RSA的安全性一直未能得到理论上的证明。

????? RSA的安全性依赖于大数难于分解这一特点。公钥和私钥都是两个大素数(大于100个
??? 十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大
??? 素数的积。

????? 密钥对的产生。选择两个大素数,p 和q 。计算:n = p * q 然后随机选择加密密钥e,
??? 要求 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 )

????? RSA 可用于数字签名,方案是用 ( a ) 式签名, ( b )式验证。具体操作时考虑到安全性
??? 和 m信息量较大等因素,一般是先作HASH 运算。RSA 的安全性。RSA的安全性依赖于大数
??? 分解,但是否等同于大数分解一直未能得到理论上的证明,因为没有证明破解RSA就一定
??? 需要作大数分解。假设存在一种无须分解大数的算法,那它肯定可以修改成为大数分解算法。
??? 目前,RSA的一些变种算法已被证明等价于大数分解。不管怎样,分解n是最显然的攻击方法。
??? 现在,人们已能分解140多个十进制位的大素数。因此,模数n必须选大一些,因具体适用情况而定。
???
??? 由于进行的都是大数计算,使得RSA最快的情况也比DES慢上100倍,无论是软件还是硬件实现。
??? 速度一直是RSA的缺陷。一般来说只用于少量数据加密。
*/
??? public struct RSA_PARAM
??? {
??????? public UInt64 p, q;?? //两个素数,不参与加密解密运算
??????? public UInt64 f;????? //f=(p-1)*(q-1),不参与加密解密运算
??????? public UInt64 n, e;?? //公匙,n=p*q,gcd(e,f)=1
??????? public UInt64 d;????? //私匙,e*d=1 (mod f),gcd(n,d)=1
??????? public UInt64 s;????? //块长,满足2^s<=n的最大的s,即log2(n)
??? };

??? class Program
??? {
??????? //小素数表
??????? #region Prime Table
??????? readonly static long[] g_PrimeTable =
??????? {
??????????? 3,
??????????? 5,
??????????? 7,
??????????? 11,
??????????? 13,
??????????? 17,
??????????? 19,
??????????? 23,
??????????? 29,
??????????? 31,
??????????? 37,
??????????? 41,
??????????? 43,
??????????? 47,
??????????? 53,
??????????? 59,
??????????? 61,
??????????? 67,
??????????? 71,
??????????? 73,
??????????? 79,
??????????? 83,
??????????? 89,
??????????? 97
??????? };
??????? #endregion

??????? readonly long g_PrimeCount = g_PrimeTable.Length;
??????? const UInt64 multiplier = 12747293821;
??????? const UInt64 adder = 1343545677842234541;

??????? //随机数类
??????? public class RandNumber
??????? {
??????????? /* */
??????????? private UInt64 randSeed;/* */
??????????? public RandNumber():this(0) { }

??????????? public RandNumber(UInt64 s)
??????????? {
??????????????? if (0 == s)//(!s)
??????????????? {
??????????????????? randSeed = (UInt64)new Random().Next();//time(NULL);
??????????????? }
??????????????? else
??????????????? {
??????????????????? randSeed = s;
??????????????? }
??????????? }
???????????
??????????? /* */
??????????? public UInt64 Random(UInt64 n)
??????????? {
??????????????? randSeed = multiplier * randSeed + adder;
??????????????? return randSeed % n;
??????????? }
??????? }

??????? static RandNumber g_Rnd = new RandNumber();

??????? /* 模乘运算,返回值 x=a*b mod n */
??????? UInt64 MulMod(UInt64 a, UInt64 b, UInt64 n)
??????? {
??????????? return a * b % n;
??????? }

??????? /* 模幂运算,返回值 x=base^pow mod n */
??????? UInt64 PowMod(UInt64 bas, UInt64 pow, UInt64 n)
??????? {
??????????? UInt64 a = bas, b = pow, c = 1;
??????????? while (b != 0)? // (b)
??????????? {
?????????