700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > RSA不对称加密 公钥加密私钥解密 私钥加密公钥解密

RSA不对称加密 公钥加密私钥解密 私钥加密公钥解密

时间:2022-07-02 08:16:59

相关推荐

RSA不对称加密 公钥加密私钥解密 私钥加密公钥解密

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。

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

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

不对称密钥

.NET Framework 为不对称加密提供了RSACryptoServiceProvider和DSACryptoServiceProvider类。这些类在您使用默认构造函数创建新实例时创建一个公钥/私钥对。既可以存储不对称密钥以用在多个会话中,也可以只为一个会话生成不对称密钥。公钥可以被广泛地使用,私钥应被严密地保护起来。

每当创建不对称算法类的新实例时,都生成一个公钥/私钥对。创建该类的新实例后,可以用以下两种方法之一提取密钥信息:

ToXMLString方法,它返回密钥信息的 XML 表示形式。导出密钥--xml形式的字符串

对应的方法:FromXmlString通过 XML 字符串中的密钥信息初始化RSA对象。导入密钥

ExportParameters方法,它返回RSAParameters结构以保存密钥信息。导出密钥--参数形式

ImportParameters导入指定的RSAParameters。(重写RSA.ImportParameters(RSAParameters)。)导入密钥

两个方法都接受布尔值,该值指示是只返回公钥信息还是同时返回公钥和私钥信息。通过使用ImportParameters方法,可以将RSACryptoServiceProvider类初始化为RSAParameters结构的值。

下面的代码示例创建RSACryptoServiceProvider类的一个新实例,创建一个公钥/私钥对,并将公钥信息保存在RSAParameters结构中

[csharp]view plaincopy //Generateapublic/privatekeypair.RSACryptoServiceProviderRSA=newRSACryptoServiceProvider();//SavethepublickeyinformationtoanRSAParametersstructure.RSAParametersRSAKeyInfo=RSA.ExportParameters(false);

一、公钥加密私钥解密

[csharp]view plaincopy ///<summary>///公钥加密,私钥解密///</summary>publicclassRSAEncryptHelper{///<summary>///将字符串使用base64算法加密///</summary>///<paramname="code_type">编码类型</param>///<paramname="code">待加密的字符串</param>///<returns>加密后的字符串</returns>publicstringEncodeBase64(stringcode_type,stringcode){stringencode="";byte[]bytes=Encoding.GetEncoding(code_type).GetBytes(code);//将一组字符编码为一个字节序列.try{encode=Convert.ToBase64String(bytes);//将8位无符号整数数组的子集转换为其等效的,以64为基的数字编码的字符串形式.}catch{encode=code;}returnencode;}///<summary>///将字符串使用base64算法解密///</summary>///<paramname="code_type">编码类型</param>///<paramname="code">已用base64算法加密的字符串</param>///<returns>解密后的字符串</returns>publicstringDecodeBase64(stringcode_type,stringcode){stringdecode="";byte[]bytes=Convert.FromBase64String(code);//将2进制编码转换为8位无符号整数数组.try{decode=Encoding.GetEncoding(code_type).GetString(bytes);//将指定字节数组中的一个字节序列解码为一个字符串。}catch{decode=code;}returndecode;}///<summary>///获取本机的MAC地址///</summary>///<returns></returns>publicstaticstringGetLocalMac(){stringmac=null;ManagementObjectSearcherquery=newManagementObjectSearcher("SELECT*FROMWin32_NetworkAdapterConfiguration");ManagementObjectCollectionqueryCollection=query.Get();foreach(ManagementObjectmoinqueryCollection){if(mo["IPEnabled"].ToString()=="True")mac=mo["MacAddress"].ToString();}return(mac);}///<summary>///得到CPU序列号///</summary>///<returns></returns>publicstaticstringGetCpuID(){try{//获取CPU序列号代码stringcpuInfo="";//cpu序列号ManagementClassmc=newManagementClass("Win32_Processor");ManagementObjectCollectionmoc=mc.GetInstances();foreach(ManagementObjectmoinmoc){cpuInfo=mo.Properties["ProcessorId"].Value.ToString();}moc=null;mc=null;returncpuInfo;}catch{return"unknow";}finally{}}///<summary>///生成公私钥///</summary>///<paramname="PrivateKeyPath"></param>///<paramname="PublicKeyPath"></param>publicvoidRSAKey(stringPrivateKeyPath,stringPublicKeyPath){try{RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();this.CreatePrivateKeyXML(PrivateKeyPath,provider.ToXmlString(true));this.CreatePublicKeyXML(PublicKeyPath,provider.ToXmlString(false));}catch(Exceptionexception){throwexception;}}///<summary>///对原始数据进行MD5加密///</summary>///<paramname="m_strSource">待加密数据</param>///<returns>返回机密后的数据</returns>publicstringGetHash(stringm_strSource){HashAlgorithmalgorithm=HashAlgorithm.Create("MD5");byte[]bytes=Encoding.GetEncoding("GB2312").GetBytes(m_strSource);byte[]inArray=puteHash(bytes);returnConvert.ToBase64String(inArray);}///<summary>///RSA加密///</summary>///<paramname="xmlPublicKey">公钥</param>///<paramname="m_strEncryptString">MD5加密后的数据</param>///<returns>RSA公钥加密后的数据</returns>publicstringRSAEncrypt(stringxmlPublicKey,stringm_strEncryptString){stringstr2;try{RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();provider.FromXmlString(xmlPublicKey);byte[]bytes=newUnicodeEncoding().GetBytes(m_strEncryptString);str2=Convert.ToBase64String(provider.Encrypt(bytes,false));}catch(Exceptionexception){throwexception;}returnstr2;}///<summary>///RSA解密///</summary>///<paramname="xmlPrivateKey">私钥</param>///<paramname="m_strDecryptString">待解密的数据</param>///<returns>解密后的结果</returns>publicstringRSADecrypt(stringxmlPrivateKey,stringm_strDecryptString){stringstr2;try{RSACryptoServiceProviderprovider=newRSACryptoServiceProvider();provider.FromXmlString(xmlPrivateKey);byte[]rgb=Convert.FromBase64String(m_strDecryptString);byte[]buffer2=provider.Decrypt(rgb,false);str2=newUnicodeEncoding().GetString(buffer2);}catch(Exceptionexception){throwexception;}returnstr2;}///<summary>///对MD5加密后的密文进行签名///</summary>///<paramname="p_strKeyPrivate">私钥</param>///<paramname="m_strHashbyteSignature">MD5加密后的密文</param>///<returns></returns>publicstringSignatureFormatter(stringp_strKeyPrivate,stringm_strHashbyteSignature){byte[]rgbHash=Convert.FromBase64String(m_strHashbyteSignature);RSACryptoServiceProviderkey=newRSACryptoServiceProvider();key.FromXmlString(p_strKeyPrivate);RSAPKCS1SignatureFormatterformatter=newRSAPKCS1SignatureFormatter(key);formatter.SetHashAlgorithm("MD5");byte[]inArray=formatter.CreateSignature(rgbHash);returnConvert.ToBase64String(inArray);}///<summary>///签名验证///</summary>///<paramname="p_strKeyPublic">公钥</param>///<paramname="p_strHashbyteDeformatter">待验证的用户名</param>///<paramname="p_strDeformatterData">注册码</param>///<returns></returns>publicboolSignatureDeformatter(stringp_strKeyPublic,stringp_strHashbyteDeformatter,stringp_strDeformatterData){try{byte[]rgbHash=Convert.FromBase64String(p_strHashbyteDeformatter);RSACryptoServiceProviderkey=newRSACryptoServiceProvider();key.FromXmlString(p_strKeyPublic);RSAPKCS1SignatureDeformatterdeformatter=newRSAPKCS1SignatureDeformatter(key);deformatter.SetHashAlgorithm("MD5");byte[]rgbSignature=Convert.FromBase64String(p_strDeformatterData);if(deformatter.VerifySignature(rgbHash,rgbSignature)){returntrue;}returnfalse;}catch{returnfalse;}}///<summary>///获取硬盘ID///</summary>///<returns>硬盘ID</returns>publicstringGetHardID(){stringHDInfo="";ManagementClasscimobject1=newManagementClass("Win32_DiskDrive");ManagementObjectCollectionmoc1=cimobject1.GetInstances();foreach(ManagementObjectmoinmoc1){HDInfo=(string)mo.Properties["Model"].Value;}returnHDInfo;}///<summary>///读注册表中指定键的值///</summary>///<paramname="key">键名</param>///<returns>返回键值</returns>privatestringReadReg(stringkey){stringtemp="";try{RegistryKeymyKey=Registry.LocalMachine;RegistryKeysubKey=myKey.OpenSubKey(@"SOFTWARE/JX/Register");temp=subKey.GetValue(key).ToString();subKey.Close();myKey.Close();returntemp;}catch(Exception){throw;//可能没有此注册项;}}///<summary>///创建注册表中指定的键和值///</summary>///<paramname="key">键名</param>///<paramname="value">键值</param>privatevoidWriteReg(stringkey,stringvalue){try{RegistryKeyrootKey=Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");rootKey.SetValue(key,value);rootKey.Close();}catch(Exception){throw;}}///<summary>///创建公钥文件///</summary>///<paramname="path"></param>///<paramname="publickey"></param>publicvoidCreatePublicKeyXML(stringpath,stringpublickey){try{FileStreampublickeyxml=newFileStream(path,FileMode.Create);StreamWritersw=newStreamWriter(publickeyxml);sw.WriteLine(publickey);sw.Close();publickeyxml.Close();}catch{throw;}}///<summary>///创建私钥文件///</summary>///<paramname="path"></param>///<paramname="privatekey"></param>publicvoidCreatePrivateKeyXML(stringpath,stringprivatekey){try{FileStreamprivatekeyxml=newFileStream(path,FileMode.Create);StreamWritersw=newStreamWriter(privatekeyxml);sw.WriteLine(privatekey);sw.Close();privatekeyxml.Close();}catch{throw;}}///<summary>///读取公钥///</summary>///<paramname="path"></param>///<returns></returns>publicstringReadPublicKey(stringpath){StreamReaderreader=newStreamReader(path);stringpublickey=reader.ReadToEnd();reader.Close();returnpublickey;}///<summary>///读取私钥///</summary>///<paramname="path"></param>///<returns></returns>publicstringReadPrivateKey(stringpath){StreamReaderreader=newStreamReader(path);stringprivatekey=reader.ReadToEnd();reader.Close();returnprivatekey;}///<summary>///初始化注册表,程序运行时调用,在调用之前更新公钥xml///</summary>///<paramname="path">公钥路径</param>publicvoidInitialReg(stringpath){Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");Randomra=newRandom();stringpublickey=this.ReadPublicKey(path);if(Registry.LocalMachine.OpenSubKey(@"SOFTWARE/JX/Register").ValueCount<=0){this.WriteReg("RegisterRandom",ra.Next(1,100000).ToString());this.WriteReg("RegisterPublicKey",publickey);}else{this.WriteReg("RegisterPublicKey",publickey);}}}

二、私钥加密公钥解密

[csharp]view plaincopy ///<summary>///非对称RSA加密类可以参考////hhh/archive//06/03/2070692.html////zhilunchen/article/details/2943158////yyl8781697/archive//04/28/RSA.html///若是私匙加密则需公钥解密///反正公钥加密私匙来解密///需要BigInteger类来辅助///</summary>publicstaticclassRSAHelper{///<summary>///RSA的容器可以解密的源字符串长度为DWKEYSIZE/8-11///</summary>publicconstintDWKEYSIZE=1024;///<summary>///RSA加密的密匙结构公钥和私匙///</summary>//publicstructRSAKey//{//publicstringPublicKey{get;set;}//publicstringPrivateKey{get;set;}//}#region得到RSA的解谜的密匙对///<summary>///得到RSA的解谜的密匙对///</summary>///<returns></returns>//publicstaticRSAKeyGetRASKey()//{//RSACryptoServiceProvider.UseMachineKeyStore=true;////声明一个指定大小的RSA容器//RSACryptoServiceProviderrsaProvider=newRSACryptoServiceProvider(DWKEYSIZE);////取得RSA容易里的各种参数//RSAParametersp=rsaProvider.ExportParameters(true);//returnnewRSAKey()//{//PublicKey=ComponentKey(p.Exponent,p.Modulus),//PrivateKey=ComponentKey(p.D,p.Modulus)//};//}#endregion#region检查明文的有效性DWKEYSIZE/8-11长度之内为有效中英文都算一个字符///<summary>///检查明文的有效性DWKEYSIZE/8-11长度之内为有效中英文都算一个字符///</summary>///<paramname="source"></param>///<returns></returns>publicstaticboolCheckSourceValidate(stringsource){return(DWKEYSIZE/8-11)>=source.Length;}#endregion#region组合解析密匙///<summary>///组合成密匙字符串///</summary>///<paramname="b1"></param>///<paramname="b2"></param>///<returns></returns>publicstaticstringComponentKey(byte[]b1,byte[]b2){List<byte>list=newList<byte>();//在前端加上第一个数组的长度值这样今后可以根据这个值分别取出来两个数组list.Add((byte)b1.Length);list.AddRange(b1);list.AddRange(b2);byte[]b=list.ToArray<byte>();returnConvert.ToBase64String(b);}///<summary>///解析密匙///</summary>///<paramname="key">密匙</param>///<paramname="b1">RSA的相应参数1</param>///<paramname="b2">RSA的相应参数2</param>privatestaticvoidResolveKey(stringkey,outbyte[]b1,outbyte[]b2){//从base64字符串解析成原来的字节数组byte[]b=Convert.FromBase64String(key);//初始化参数的数组长度b1=newbyte[b[0]];b2=newbyte[b.Length-b[0]-1];//将相应位置是值放进相应的数组for(intn=1,i=0,j=0;n<b.Length;n++){if(n<=b[0]){b1[i++]=b[n];}else{b2[j++]=b[n];}}}#endregion#region字符串加密解密公开方法///<summary>///字符串加密///</summary>///<paramname="source">源字符串明文</param>///<paramname="key">密匙</param>///<returns>加密遇到错误将会返回原字符串</returns>publicstaticstringEncryptString(stringsource,stringkey){stringencryptString=string.Empty;byte[]d;byte[]n;try{if(!CheckSourceValidate(source)){thrownewException("sourcestringtoolong");}//解析这个密钥ResolveKey(key,outd,outn);BigIntegerbiN=newBigInteger(n);BigIntegerbiD=newBigInteger(d);encryptString=EncryptString(source,biD,biN);}catch{encryptString=source;}returnencryptString;}///<summary>///字符串解密///</summary>///<paramname="encryptString">密文</param>///<paramname="key">密钥</param>///<returns>遇到解密失败将会返回空字符串</returns>publicstaticstringDecryptString(stringencryptString,stringkey){stringsource=string.Empty;byte[]e;byte[]n;try{//解析这个密钥ResolveKey(key,oute,outn);BigIntegerbiE=newBigInteger(e);BigIntegerbiN=newBigInteger(n);source=DecryptString(encryptString,biE,biN);}catch{}returnsource;}#endregion#region字符串加密解密私有实现加解密的实现方法///<summary>///用指定的密匙加密///</summary>///<paramname="source">明文</param>///<paramname="d">可以是RSACryptoServiceProvider生成的D</param>///<paramname="n">可以是RSACryptoServiceProvider生成的Modulus</param>///<returns>返回密文</returns>privatestaticstringEncryptString(stringsource,BigIntegerd,BigIntegern){intlen=source.Length;intlen1=0;intblockLen=0;if((len%128)==0)len1=len/128;elselen1=len/128+1;stringblock="";StringBuilderresult=newStringBuilder();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);stringtemp=biEnText.ToHexString();result.Append(temp).Append("@");len-=blockLen;}returnresult.ToString().TrimEnd('@');}///<summary>///用指定的密匙加密///</summary>///<paramname="source">密文</param>///<paramname="e">可以是RSACryptoServiceProvider生成的Exponent</param>///<paramname="n">可以是RSACryptoServiceProvider生成的Modulus</param>///<returns>返回明文</returns>privatestaticstringDecryptString(stringencryptString,BigIntegere,BigIntegern){StringBuilderresult=newStringBuilder();string[]strarr1=encryptString.Split(newchar[]{'@'},StringSplitOptions.RemoveEmptyEntries);for(inti=0;i<strarr1.Length;i++){stringblock=strarr1[i];BigIntegerbiText=newBigInteger(block,16);BigIntegerbiEnText=biText.modPow(e,n);stringtemp=System.Text.Encoding.Default.GetString(biEnText.getBytes());result.Append(temp);}returnresult.ToString();}#endregion///<summary>///将字符串使用base64算法加密///</summary>///<paramname="code_type">编码类型</param>///<paramname="code">待加密的字符串</param>///<returns>加密后的字符串</returns>publicstaticstringEncodeBase64(stringcode_type,stringcode){stringencode="";byte[]bytes=Encoding.GetEncoding(code_type).GetBytes(code);//将一组字符编码为一个字节序列.try{encode=Convert.ToBase64String(bytes);//将8位无符号整数数组的子集转换为其等效的,以64为基的数字编码的字符串形式.}catch{encode=code;}returnencode;}///<summary>///将字符串使用base64算法解密///</summary>///<paramname="code_type">编码类型</param>///<paramname="code">已用base64算法加密的字符串</param>///<returns>解密后的字符串</returns>publicstaticstringDecodeBase64(stringcode_type,stringcode){stringdecode="";byte[]bytes=Convert.FromBase64String(code);//将2进制编码转换为8位无符号整数数组.try{decode=Encoding.GetEncoding(code_type).GetString(bytes);//将指定字节数组中的一个字节序列解码为一个字符串。}catch{decode=code;}returndecode;}///<summary>///读取公钥或私钥///</summary>///<paramname="includePrivateparameters">为True则包含私钥</param>///<paramname="path">Xml格式保存的完整公/私钥路径</param>///<returns>公钥或私钥参数形式</returns>publicstaticRSAParametersReadKey(boolincludePrivateparameters,stringpath){using(StreamReaderreader=newStreamReader(path)){stringpublickey=reader.ReadToEnd();RSACryptoServiceProviderrcp=newRSACryptoServiceProvider();rcp.FromXmlString(publickey);returnrcp.ExportParameters(includePrivateparameters);}}///<summary>///获取本机的MAC地址///</summary>///<returns></returns>publicstaticstringGetLocalMac(){stringmac=null;ManagementObjectSearcherquery=newManagementObjectSearcher("SELECT*FROMWin32_NetworkAdapterConfiguration");ManagementObjectCollectionqueryCollection=query.Get();foreach(ManagementObjectmoinqueryCollection){if(mo["IPEnabled"].ToString()=="True")mac=mo["MacAddress"].ToString();}return(mac);}///<summary>///得到CPU序列号///</summary>///<returns></returns>publicstaticstringGetCpuID(){try{//获取CPU序列号代码stringcpuInfo="";//cpu序列号ManagementClassmc=newManagementClass("Win32_Processor");ManagementObjectCollectionmoc=mc.GetInstances();foreach(ManagementObjectmoinmoc){cpuInfo=mo.Properties["ProcessorId"].Value.ToString();}moc=null;mc=null;returncpuInfo;}catch{return"unknow";}finally{}}///<summary>///获取硬盘ID///</summary>///<returns>硬盘ID</returns>publicstaticstringGetHardID(){stringHDInfo="";ManagementClasscimobject1=newManagementClass("Win32_DiskDrive");ManagementObjectCollectionmoc1=cimobject1.GetInstances();foreach(ManagementObjectmoinmoc1){HDInfo=(string)mo.Properties["Model"].Value;}returnHDInfo;}///<summary>///读注册表中指定键的值///</summary>///<paramname="key">键名</param>///<returns>返回键值</returns>privatestaticstringReadReg(stringkey){stringtemp="";try{RegistryKeymyKey=Registry.LocalMachine;RegistryKeysubKey=myKey.OpenSubKey(@"SOFTWARE/JX/Register");temp=subKey.GetValue(key).ToString();subKey.Close();myKey.Close();returntemp;}catch(Exception){throw;//可能没有此注册项;}}///<summary>///创建注册表中指定的键和值///</summary>///<paramname="key">键名</param>///<paramname="value">键值</param>privatestaticvoidWriteReg(stringkey,stringvalue){try{RegistryKeyrootKey=Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");rootKey.SetValue(key,value);rootKey.Close();}catch(Exception){throw;}}}

使用场景:如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

RSA算法实现激活码注册方式的原理如下:

1.生成一对公钥E和私钥D(供软件注册模板和注册机使用);

2.用户安装软件后,软件注册模板提取用户机器指纹信息(如:MAC地址、CPU序列号、硬盘序列号等),并通过其它的编码算法(如BASE64)生成一个申请码C;

3.用户将申请码C发给软件开发商。软件开发商通过注册机采用私钥D加密申请码C后生成激活码F。软件供应商将激活码F发给用户。

4.用户输入激活码F,软件注册模板采用公钥E对激活码F解码后生成G(即:用户机器特征信息),然后软件注册模板提取用户机器的特定信息后进行编码。将编码的结果与G进行比较,如果相等则用户合法,完成授权,否则授权失败。

[csharp]view plaincopy //应用程序注册模块publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidForm1_Load(objectsender,EventArgse){stringcpu=RSAHelper.GetCpuID();string_申请码C=RSAHelper.EncodeBase64("utf-8",cpu);textEdit申请码.Text=_申请码C;}privatevoidsimpleButton注册_Click(objectsender,EventArgse){stringpublicKeyPath=@"C://PublicKey.xml";RSAParameterspm=RSAHelper.ReadKey(false,publicKeyPath);string_PublicKey=ponentKey(pm.Exponent,pm.Modulus);stringcpu=RSAHelper.DecryptString(textEdit激活码.Text,_PublicKey);if(cpu==textEdit申请码.Text){MessageBox.Show("注册成功");}else{MessageBox.Show("注册失败");}}}[csharp]view plaincopy ///<summary>///注册机///</summary>publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privatevoidsimpleButton生成激活码_Click(objectsender,EventArgse){stringprivateKeyPath=@"C://PrivateKey.xml";RSAParameterspm=RSAHelper.ReadKey(true,privateKeyPath);string_PrivateKey=ponentKey(pm.D,pm.Modulus);textEdit激活码.Text=RSAHelper.EncryptString(textEdit申请码.Text,_PrivateKey);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。