RSA算法是第一個能同時用于加密和數(shù)字簽名的算法,也易于理解和操作。 RSA是被研究得最廣泛的公鑰算法,從提出到現(xiàn)在已近二十年,經(jīng)歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優(yōu)秀的公鑰方案之一。RSA的安全性依賴于大數(shù)的因子分解,但并沒有從理論上證明破譯RSA的難度與大數(shù)分解難度等價。RSA的安全性依賴于大數(shù)分解。公鑰和私鑰都是兩個大素數(shù)( 大于 100個十進制位)的函數(shù)。據(jù)猜測,從一個密鑰和密文推斷出明文的難度等同于分解兩個大素數(shù)的積。密鑰對的產(chǎn)生。選擇兩個大素數(shù),p 和q 。計算: n = p * q然后隨機選擇加密密鑰e(PS:最常用的e值有3,17和65537,微軟就是使用的65537,采用3個中的任何一個都不存在安全問題),要求 e 和 ( p - 1 ) * ( q - 1 ) 互質(zhì)。最后,利用Euclid 算法計算解密密鑰d, 滿足 e * d = 1 ( mod ( p - 1 ) * ( q - 1 ) )其中n和d也要互質(zhì)。數(shù)e和n是公鑰,d是私鑰。兩個素數(shù)p和q不再需要,應(yīng)該丟棄,不要讓任何人知道。加密信息 m(二進制表示)時,首先把m分成等長數(shù)據(jù)塊 m1 ,m2,..., mi ,塊長s,其中 2^s <= n, s 盡可能的大。對應(yīng)的密文是: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類提供導(dǎo)出公鑰的方法,也提供導(dǎo)出私鑰的方法,但導(dǎo)出的私鑰包含上面8個屬性,顯然要用RSACryptoServiceProvider實現(xiàn)私鑰加密公鑰是不可行的。
從RSA的原理來看,公鑰加密私鑰解密和私鑰加密公鑰解密應(yīng)該是等價的,在某些情況下,比如共享軟件加密,我們需要用私鑰加密注冊碼或注冊文件,發(fā)給用戶,用戶用公鑰解密注冊碼或注冊文件進行合法性驗證。
本人利用網(wǎng)上找的一個C#版的大整數(shù)類BigInteger(本人認為這是偶發(fā)現(xiàn)的效率最高的一個C#版大整數(shù)類)來實現(xiàn)私鑰加密公鑰加密(事實上也完全支持公租加密私鑰解密),但沒有使用類BigInteger的大素數(shù)生成函數(shù),而是直接使用類RSACryptoServiceProvider來生成大素數(shù)。其中加密函數(shù)和解密函數(shù)的實現(xiàn)如下:
/*功能:用指定的私鑰(n,d)加密指定字符串source*/privatestringEncryptString(stringsource,BigIntegerd,BigIntegern){intlen=source.Length;intlen1=0;intblockLen=0;if((len%128)==0)len1=len/128;elselen1=len/128+1;stringblock="";stringtemp="";for(inti=0;i<len1;i++){if(len>=128)blockLen=128;elseblockLen=len;block=source.Substring(i*128,blockLen);byte[]oText=System.Text.Encoding.Default.GetBytes(block);BigIntegerbiText=newBigInteger(oText);BigIntegerbiEnText=biText.modPow(d,n);stringtemp1=biEnText.ToHexString();temp+=temp1;len-=blockLen;}returntemp;}/*功能:用指定的公鑰(n,e)解密指定字符串source*/privatestringDecryptString(stringsource,BigIntegere,BigIntegern){intlen=source.Length;intlen1=0;intblockLen=0;if((len%256)==0)len1=len/256;elselen1=len/256+1;stringblock="";stringtemp="";for(inti=0;i<len1;i++){if(len>=256)blockLen=256;elseblockLen=len;block=source.Substring(i*256,blockLen);BigIntegerbiText=newBigInteger(block,16);BigIntegerbiEnText=biText.modPow(e,n);stringtemp1=System.Text.Encoding.Default.GetString(biEnText.getBytes());temp+=temp1;len-=blockLen;}returntemp;}加密過程和解密過程代碼如下所示:/*加密過程,其中d、n是RSACryptoServiceProvider生成的D、Modulus*/privatestringEncryptProcess(stringsource,stringd,stringn){byte[]N=Convert.FromBase64String(n);byte[]D=Convert.FromBase64String(d);BigIntegerbiN=newBigInteger(N);BigIntegerbiD=newBigInteger(D);returnEncryptString(source,biD,biN);}/*解密過程,其中e、n是RSACryptoServiceProvider生成的Exponent、Modulus*/privatestringDecryptProcess(stringsource,stringe,stringn){byte[]N=Convert.FromBase64String(n);byte[]E=Convert.FromBase64String(e);BigIntegerbiN=newBigInteger(N);BigIntegerbiE=newBigInteger(E);returnDecryptString(source,biE,biN);}
新聞熱點
疑難解答