下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

RSA加解密算法讲解

作者:课课家教育     来源: http://www.kokojia.com点击数:1866发布时间: 2017-04-27 08:00:39

标签: 公开密钥密码体制网络安全技术网络工程师

   RSA公钥加密算法是1977年由罗纳德·李维斯特(RonRivest)、阿迪·萨莫尔(AdiShamir)和伦纳德·阿德曼(LeonardAdleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

一、什么是RSA

  RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

  在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

  RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现在的三十多年里,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。

  今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战。

  RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

  二、RSA算法密钥长度的选择

RSA加解密算法讲解_公开密钥密码体制_网络安全技术_网络工程师

  1.非对称加密算法中1024bit密钥的强度相当于对称加密算法80bit密钥的强度。

  2.密钥长度增长一倍,公钥操作所需时间增加约4倍,私钥操作所需时间增加约8倍,公私钥生成时间约增长16倍。

  3.一次能加密的密文长度与密钥长度成正比,加密后的密文长度跟密钥长度相同(RSA加密内容的长度有限制,和密钥长度有关,这是由它的算法决定的)

  a、加密的明文长度不能超过RSA密钥的长度减去11byte,比如密钥长度是1024位的,1024位=1024bit=128byte,128-11=117byte,所以明文长度不能超过117byte,如果长度超过该值将会抛出异常。

  b、加密后密文的长度为密钥的长度,如密钥长度为1024bit(128Byte),最后生成的密文固定为1024bit(128Byte)。

  三、C#中的RSA加解密

  .NETFramework类库提供了System.Security命名空间,System.Security命名空间提供公共语言运行时安全系统的基础结构,包括权限的基类,而该命名空间下提供了RSACryptoServiceProvider类来执行RSA算法的不对称加密和解密。

  1.密钥对的生成:

  a、根据RSACryptoServiceProvider直接生成

  复制代码

  ///<summary>

  ///生成密钥

  ///</summary>

  publicRSAKeyGenerateRSAKey()

  {

  RSAKeyRSAKEY=newRSAKey();

  RSACryptoServiceProviderRSA=newRSACryptoServiceProvider();

  RSAKEY.PrivateKey=RSA.ToXmlString(true);//生成私钥

  RSAKEY.PublicKey=RSA.ToXmlString(false);//生成公钥

  RSA.Clear();

  returnRSAKEY;

  }

  复制代码

  b、通过Makecert证书创建工具生成安全证书

  makecert-r-pe-n"CN=RSAKey"-b03/31/2005-e12/31/2012-skyexchange-ssmy

  可通过"VisualStudio命令提示行"执行以上命令生成证书。

  查看生成的证书:

  运行->输入mmc打开控制台->选择文件->添加/删除管理单元->在弹出框左侧找到证书->选中证书添加->选择我的用户账户->完成确定

  此时就可以在对应位置查看到我们刚刚创建的名为RSAKey的证书了,如下图:

运行->输入mmc打开控制台->选择文件->添加/删除管理单元->在弹出框左侧找到证书->选中证书添加->选择我的用户账户->完成确定    此时就可以在对应位置查看到我们刚刚创建的名为RSAKey的证书了,如下图

  最终我们可以将证书导出为:

  其中RSAKey.cer中含有加密用的公钥,RSAKey.pfx中含有解密用的私钥。

  2.创建加解密RSA

  复制代码

  ///<summary>

  ///创建加密RSA

  ///</summary>

  ///<paramname="publicKey">公钥</param>

  ///<returns></returns>

  privateRSACryptoServiceProviderCreateEncryptRSA(stringpublicKey)

  {

  try

  {

  RSACryptoServiceProviderRSA=newRSACryptoServiceProvider();

  RSA.FromXmlString(publicKey);

  returnRSA;

  }

  catch(CryptographicExceptionex)

  {

  throwex;

  }

  }

  ///<summary>

  ///创建解密RSA

  ///</summary>

  ///<paramname="privateKey">私钥</param>

  ///<returns></returns>

  privateRSACryptoServiceProviderCreateDecryptRSA(stringprivateKey)

  {

  try

  {

  RSACryptoServiceProviderRSA=newRSACryptoServiceProvider();

  RSA.FromXmlString(privateKey);

  returnRSA;

  }

  catch(CryptographicExceptionex)

  {

  throwex;

  }

  }

  ///<summary>

  ///根据安全证书创建加密RSA

  ///</summary>

  ///<paramname="certfile">公钥文件</param>

  ///<returns></returns>

  privateRSACryptoServiceProviderX509CertCreateEncryptRSA(stringcertfile)

  {

  try

  {

  X509Certificate2x509Cert=newX509Certificate2(certfile);

  RSACryptoServiceProviderRSA=(RSACryptoServiceProvider)x509Cert.PublicKey.Key;

  returnRSA;

  }

  catch(CryptographicExceptionex)

  {

  throwex;

  }

  }

  ///<summary>

  ///根据私钥文件创建解密RSA

  ///</summary>

  ///<paramname="keyfile">私钥文件</param>

  ///<paramname="password">访问含私钥文件的密码</param>

  ///<returns></returns>

  privateRSACryptoServiceProviderX509CertCreateDecryptRSA(stringkeyfile,stringpassword)

  {

  try

  {

  X509Certificate2x509Cert=newX509Certificate2(keyfile,password);

  RSACryptoServiceProviderRSA=(RSACryptoServiceProvider)x509Cert.PrivateKey;

  returnRSA;

  }

  catch(CryptographicExceptionex)

  {

  throwex;

  }

  }

  复制代码

  其中所提及的私钥文件和公钥文件就是根据Makecert证书创建工具生成安全证书,而X509CertCreateDecryptRSA方法中的参数password是我们导出私钥文件所设置的访问密码,如果没有改密码即使有私钥证书也没办法解密。

  3.RSA加解密

  复制代码

  ///<summary>

  ///加密

  ///</summary>

  ///<paramname="dataToEncrypt">待加密数据</param>

  ///<paramname="publicKey">公钥</param>

  ///<returns></returns>

  publicstringEncrypt(stringdataToEncrypt,stringpublicKey)

  {

  Encodingencoder=Encoding.UTF8;

  byte[]_dataToEncrypt=encoder.GetBytes(dataToEncrypt);

  returnthis.Encrypt(_dataToEncrypt,publicKey);

  }

  ///<summary>

  ///加密

  ///</summary>

  ///<paramname="dataToEncrypt">待加密数据</param>

  ///<paramname="publicKey">公钥</param>

  ///<returns></returns>

  publicstringEncrypt(byte[]dataToEncrypt,stringpublicKey)

  {

  using(RSACryptoServiceProviderRSA=this.CreateEncryptRSA(publicKey))

  {

  byte[]encryptedData=RSA.Encrypt(dataToEncrypt,false);

  returnthis.BytesToHexString(encryptedData);

  }

  }

  ///<summary>

  ///根据安全证书加密

  ///</summary>

  ///<paramname="dataToEncrypt"></param>

  ///<paramname="certfile"></param>

  ///<returns></returns>

  publicstringX509CertEncrypt(stringdataToEncrypt,stringcertfile)

  {

  Encodingencoder=Encoding.UTF8;

  byte[]_dataToEncrypt=encoder.GetBytes(dataToEncrypt);

  returnthis.X509CertEncrypt(_dataToEncrypt,certfile);

  }

  ///<summary>

  ///根据安全证书加密

  ///</summary>

  ///<paramname="dataToEncrypt">待加密数据</param>

  ///<paramname="certfile">安全证书</param>

  ///<returns></returns>

  publicstringX509CertEncrypt(byte[]dataToEncrypt,stringcertfile)

  {

  if(!File.Exists(certfile))

  {

  thrownewArgumentNullException(certfile,"加密证书未找到");

  }

  using(RSACryptoServiceProviderRSA=this.X509CertCreateEncryptRSA(certfile))

  {

  byte[]encryptedData=RSA.Encrypt(dataToEncrypt,false);

  returnthis.BytesToHexString(encryptedData);

  }

  }

  ///<summary>

  ///解密

  ///</summary>

  ///<paramname="encryptedData">待解密数据</param>

  ///<paramname="privateKey">私钥</param>

  ///<returns></returns>

  publicstringDecrypt(stringencryptedData,stringprivateKey)

  {

  using(RSACryptoServiceProviderRSA=this.CreateDecryptRSA(privateKey))

  {

  Encodingencoder=Encoding.UTF8;

  byte[]_encryptedData=HexStringToBytes(encryptedData);

  byte[]decryptedData=RSA.Decrypt(_encryptedData,false);

  returnencoder.GetString(decryptedData);

  }

  }

  ///<summary>

  ///解密

  ///</summary>

  ///<paramname="encryptedData">待解密数据</param>

  ///<paramname="keyfile">私钥文件</param>

  ///<paramname="password">访问私钥文件密码</param>

  ///<returns></returns>

  publicstringX509CertDecrypt(stringencryptedData,stringkeyfile,stringpassword)

  {

  if(!File.Exists(keyfile))

  {

  thrownewArgumentNullException(keyfile,"解密证书未找到");

  }

  using(RSACryptoServiceProviderRSA=this.X509CertCreateDecryptRSA(keyfile,password))

  {

  Encodingencoder=Encoding.UTF8;

  byte[]_encryptedData=HexStringToBytes(encryptedData);

  byte[]decryptedData=RSA.Decrypt(_encryptedData,false);

  returnencoder.GetString(decryptedData);

  }

  }

  复制代码

  最后整理了一个简单的Demo:

  复制代码 最后整理了一个简单的Demo

    其中所提及的私钥文件和公钥文件就是根据Makecert证书创建工具生成安全证书,而X509CertCreateDecryptRSA方法中的参数password是我们出私钥文件所设置的访问密码,如果没有改密码即使有私钥证书也没办法解密。想要了解更多知识,尽在课课家哦~

赞(26)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程