分享
 
 
 

把网友的RSA加密代码转换到C#

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

实际没做什么事情,想起来也无耻,不过可能有些朋友比较懒的话,也会有一点用的。在此先向 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)

??????????? {

??????????????? while (1 != (b & 1))??? // !(b&1)

??????????????? {

??????????????????? b >>= 1;??????????? //a=a * a % n;??? //函数看起来可以处理64位的整数,但由于这里a*a在a>=2^32时已经造成了溢出,因此实际处理范围没有64位

??????????????????? a = MulMod(a, a, n);

??????????????? } b--;??????? //c=a * c % n;??????? //这里也会溢出,若把64位整数拆为两个32位整数不知是否可以解决这个问题。

??????????????? c = MulMod(a, c, n);

??????????? } return c;

??????? }

??????? /*

??????? Rabin-Miller素数测试,通过测试返回1,否则返回0。

??????? n是待测素数。

??????? 注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4

??????? */

??????? long RabinMillerKnl(UInt64 n)

??????? {

??????????? UInt64 b, m, j, v, i;

??????????? m = n - 1;

??????????? j = 0;??? //0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数

??????????? while (1 != (m&1))??? // (!(m & 1))

??????????? {

??????????????? ++j;

??????????????? m >>= 1;

??????????? }??? //1、随机取一个b,2<=b

??????????? b = 2 + g_Rnd.Random(n - 3);??? //2、计算v=b^m mod n

??????????? v = PowMod( b,? m,? n);??? //3、如果v==1,通过测试

??????????? if (v == 1)

??????????? {

??????????????? return 1;

??????????? }??? //4、令i=1

??????????? i = 1;??? //5、如果v=n-1,通过测试

??????????? while (v != n - 1)

??????????? {

??????????????? //6、如果i==l,非素数,结束

??????????????? if (i == j)

??????????????? {

??????????????????? return 0;

??????????????? }??????? //7、v=v^2 mod n,i=i+1

??????????????? v = PowMod( v, 2,? n);

??????????????? ++i;??????? //8、循环到5

??????????? } return 1;

??????? }

??????? /*

??????? Rabin-Miller素数测试,循环调用核心loop次

??????? 全部通过返回1,否则返回0

??????? */

??????? long RabinMiller(UInt64 n, long loop)

??????? {

??????????? //先用小素数筛选一次,提高效率

??????????? for (long i = 0; i < g_PrimeCount; i++)

??????????? {

??????????????? if ((n % unchecked((ulong)g_PrimeTable[i])) == 0)

??????????????? {

??????????????????? return 0;

??????????????? }

??????????? }

??????????? //循环调用Rabin-Miller测试loop次,使得非素数通过测试的概率降为(1/4)^loop

??????????? for (long i = 0; i < loop; i++)

??????????? {

??????????????? if (0 == RabinMillerKnl(n)) //(! ...)

??????????????? {

??????????????????? return 0;

??????????????? }

??????????? } return 1;

??????? }

??????? /* 随机生成一个bits位(二进制位)的素数,最多32位 */

??????? UInt64 RandomPrime(char bits)

??????? {

??????????? UInt64 bas;

??????????? do

??????????? {

??????????????? bas = (UInt32)1 << (bits - 1);?? //保证最高位是1

??????????????? bas += g_Rnd.Random(bas);?????????????? //再加上一个随机数

??????????????? bas |= 1;??? //保证最低位是1,即保证是奇数

??????????? } while (0 == RabinMiller(bas, 30)); // (!RabinMiller(bas, 30))??? //进行拉宾-米勒测试30次

??????????? return bas;??? //全部通过认为是素数

??????? }

??????? /* 欧几里得法求最大公约数 */

??????? UInt64 EuclidGcd(UInt64 p, UInt64 q)

??????? {

??????????? UInt64 a = p > q ? p : q;

??????????? UInt64 b = p < q ? p : q;

??????????? UInt64 t;

??????????? if (p == q)

??????????? {

??????????????? return p;?? //两数相等,最大公约数就是本身

??????????? }

??????????? else

??????????? {

??????????????? while (0 != b) //(b)??? //辗转相除法,gcd(a,b)=gcd(b,a-qb)

??????????????? {

??????????????????? a = a % b;

??????????????????? t = a;

??????????????????? a = b;

??????????????????? b = t;

??????????????? } return a;

??????????? }

??????? }

??????? /* Stein法求最大公约数 */

??????? UInt64 SteinGcd( UInt64 p,? UInt64 q)

??????? {

??????????? UInt64 a = p > q ? p : q;

??????????? UInt64 b = p < q ? p : q;

??????????? UInt64 t, r = 1;

??????????? if (p == q)

??????????? {

??????????????? return p;?????????? //两数相等,最大公约数就是本身

??????????? }

??????????? else

??????????? {

??????????????? //while ((!(a & 1)) && (!(b & 1)))

??????????????? while ((0 ==(a & 1)) && (0 ==(b & 1)))

??????????????? {

??????????????????? r <<= 1;????????? //a、b均为偶数时,gcd(a,b)=2*gcd(a/2,b/2)

??????????????????? a >>= 1;

??????????????????? b >>= 1;

??????????????? }

??????????????? if (0 == (a&1))//(!(a & 1))

??????????????? {

??????????????????? t = a;??????????? //如果a为偶数,交换a,b

??????????????????? a = b;

??????????????????? b = t;

??????????????? } do

??????????????? {

??????????????????? while (0 == (b & 1))//(!(b & 1))

??????????????????? {

??????????????????????? b >>= 1;????? //b为偶数,a为奇数时,gcd(b,a)=gcd(b/2,a)

??????????????????? } if (b < a)

??????????????????? {

??????????????????????? t = a;??????? //如果b小于a,交换a,b

??????????????????????? a = b;

??????????????????????? b = t;

??????????????????? } b = (b - a) >> 1; //b、a都是奇数,gcd(b,a)=gcd((b-a)/2,a)

??????????????? } while (b != 0); //(b);

??????????????? return r * a;

??????????? }

??????? }

??????? /*

??????? 已知a、b,求x,满足a*x =1 (mod b)

??????? 相当于求解a*x-b*y=1的最小整数解

??????? */

??????? UInt64 Euclid(UInt64 a, UInt64 b)

??????? {

??????????? UInt64 m, e, i, j, x, y;

??????????? long xx, yy;

??????????? m = b;

??????????? e = a;

??????????? x = 0;

??????????? y = 1;

??????????? xx = 1;

??????????? yy = 1;

??????????? while (0 != e)//(e)

??????????? {

??????????????? i = m / e;

??????????????? j = m % e;

??????????????? m = e;

??????????????? e = j;

??????????????? j = y;

??????????????? y *= i;

??????????????? if (xx == yy)

??????????????? {

??????????????????? if (x > y)

??????????????????? {

??????????????????????? y = x - y;

??????????????????? }

??????????????????? else

??????????????????? {

??????????????????????? y -= x;

??????????????????????? yy = 0;

??????????????????? }

??????????????? }

??????????????? else

??????????????? {

??????????????????? y += x;

??????????????????? xx = 1 - xx;

??????????????????? yy = 1 - yy;

??????????????? } x = j;

??????????? }

??????????? if (xx == 0)

??????????? {

??????????????? x = b - x;

??????????? } return x;

??????? }

??????? /* 随机产生一个RSA加密参数 */

??????? RSA_PARAM RsaGetParam()

??????? {

??????????? RSA_PARAM Rsa =new RSA_PARAM();

??????????? UInt64 t;

??????????? Rsa.p = RandomPrime((char)16);????????? //随机生成两个素数

??????????? Rsa.q = RandomPrime((char)16);

??????????? Rsa.n = Rsa.p * Rsa.q;

??????????? Rsa.f = (Rsa.p - 1) * (Rsa.q - 1);

??????????? do

??????????? {

??????????????? Rsa.e = g_Rnd.Random(65536);? //小于2^16,65536=2^16

??????????????? Rsa.e |= 1;?????????????????? //保证最低位是1,即保证是奇数,因f一定是偶数,要互素,只能是奇数

??????????? } while (SteinGcd(Rsa.e, Rsa.f) != 1); Rsa.d = Euclid(Rsa.e, Rsa.f);

??????????? Rsa.s = 0;

??????????? t = Rsa.n >> 1;

??????????? while (0 != t)//(t)

??????????? {

??????????????? Rsa.s++;??????????????????? //s=log2(n)

??????????????? t >>= 1;

??????????? } return Rsa;

??????? }

??????? /* 拉宾-米勒测试 */

??????? void TestRM()

??????? {

??????????? UInt32 k = 0;

??????????? Console.Write(" - Rabin-Miller prime check.\n\n");

??????????? for (UInt64 i = 4197900001; i < 4198000000; i += 2)

??????????? {

??????????????? if (0 != RabinMiller(i, 30))

??????????????? {

??????????????????? k++;

??????????????????? Console.WriteLine(i);

??????????????? }

??????????? }

??????????? Console.WriteLine("Total: " + k);

??????? }

??????? /* RSA加密解密 */

??????? void TestRSA()

??????? {

??????????? RSA_PARAM r;

??????????? string pSrc = "abcdefghijklmnopqrstuvwxyz";

??????????? UInt32 n = (uint)pSrc.Length;

??????????? //unsigned char?????? *q, pDec[n];

??????????? byte[] pDec = new byte[n];

??????????? UInt64[] pEnc = new UInt64[n];

??????????? r = RsaGetParam();

??????????? Console.WriteLine("p=" + r.p);

??????????? Console.WriteLine("q=" + r.q);

??????????? Console.WriteLine("f=(p-1)*(q-1)=" + r.f);

??????????? Console.WriteLine("n=p*q=" + r.n);

??????????? Console.WriteLine("e=" + r.e);

??????????? Console.WriteLine("d=" + r.d);

??????????? Console.WriteLine("s=" + r.s);

??????????? Console.WriteLine("Source:" + pSrc);

??????????? //q= (unsigned char *)pSrc;

??????????? Console.Write("Encode:");

??????????? for (int i = 0; i < (int)n; i++)

??????????? {

??????????????? //pEnc[i]=PowMod(q[i], r.e, r.n);

??????????????? pEnc[i] = PowMod((ulong)pSrc[i], r.e, r.n);

??????????????? Console.Write(pEnc[i].ToString() + " ");

??????????? } Console.WriteLine("");

??????????? Console.Write("Decode:");

??????????? for (int i = 0; i < (int)n; i++)

??????????? {

??????????????? pDec[i] = (byte)PowMod((ulong)pEnc[i], r.d, r.n);

??????????????? Console.Write((UInt32)pDec[i] + " ");

??????????? } Console.WriteLine("");

??????????? Console.WriteLine(Encoding.Default.GetString(pDec));

??????? }/* */

??????? static void Main(string[] args)

??????? {

??????????? new Program().TestRSA();

??????? }

??? }

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有