<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      net加密基礎(chǔ)2-非對(duì)稱加密

      2012-02-09 20:31  海不是藍(lán)  閱讀(2541)  評(píng)論(6)    收藏  舉報(bào)

      非對(duì)稱密碼算法

      非對(duì)稱密碼算法使用2個(gè)不同但在數(shù)學(xué)上卻相關(guān)的密鑰。用于加密數(shù)據(jù)的密鑰不能用于解密。

      非對(duì)稱密碼技術(shù)統(tǒng)稱稱為“公鑰加密技術(shù)”,沒(méi)有雙方必要保密的單個(gè)密鑰。

      公鑰加密技術(shù)只有一個(gè)必須由一方保密的私鑰,第二個(gè)密鑰就是公鑰,任何想與他們通信的人都可以隨意使用它。

      安全web通信就是采用的這種技術(shù)。該技術(shù)可以用于電子商務(wù)。

       

      非對(duì)稱和對(duì)稱的區(qū)別

      對(duì)稱加密和非對(duì)稱加密的密鑰類型分別是私鑰和公鑰。

       

      對(duì)稱加密使用的是私鑰加密,也就是密鑰只能是加密者和解密者知道,第3方不能知道。

      而非對(duì)稱加密情況完全不一樣,非對(duì)稱加密有2個(gè)不同的密鑰,一個(gè)是公共的密鑰,一個(gè)是私有的密鑰,公鑰是可以讓外人知道的,因?yàn)楣€只用來(lái)加密數(shù)據(jù),而私鑰只能由解密方知道,只有私鑰能解密!

       

      官方的啰嗦!

      公鑰加密使用一個(gè)必須對(duì)未經(jīng)授權(quán)的用戶保密的私鑰和一個(gè)可以對(duì)任何人公開(kāi)的公鑰。公鑰和私鑰都在數(shù)學(xué)上相關(guān)聯(lián);用公鑰加密的數(shù)據(jù)只能用私鑰解密,而用私鑰簽名的數(shù)據(jù)只能用公鑰驗(yàn)證。公鑰可以提供給任何人;公鑰用于對(duì)要發(fā)送到私鑰持有者的數(shù)據(jù)進(jìn)行加密。兩個(gè)密鑰對(duì)于通信會(huì)話都是唯一的。公鑰加密算法也稱為不對(duì)稱算法,原因是需要用一個(gè)密鑰加密數(shù)據(jù)而需要用另一個(gè)密鑰來(lái)解密數(shù)據(jù)。

       

      經(jīng)典的小紅和小明

      雙方(小紅和小明)可以按照下列方式使用公鑰加密。首先,小紅生成一個(gè)公鑰/私鑰對(duì)。如果小明想要給小紅發(fā)送一條加密的消息,他將向她索要她的公鑰。小紅通過(guò)不安全的網(wǎng)絡(luò)將她的公鑰發(fā)送給小明,小明接著使用該密鑰加密消息。(如果小明在不安全的信道如公共網(wǎng)絡(luò)上收到小紅的密鑰,則小明必須同小紅驗(yàn)證他具有她的公鑰的正確副本。)小明將加密的消息發(fā)送給小紅,而小紅使用她的私鑰解密該消息。

       

      但是,在傳輸小紅的公鑰期間,未經(jīng)授權(quán)的代理可能截獲該密鑰。而且,同一代理可能截獲來(lái)自小明的加密消息。但是,該代理無(wú)法用公鑰解密該消息。該消息只能用小紅的私鑰解密,而該私鑰沒(méi)有被傳輸。小紅不使用她的私鑰加密給小明的答復(fù)消息,原因是任何具有公鑰的人都可以解密該消息。如果小紅想要將消息發(fā)送回小明,她將向小明索要他的公鑰并使用該公鑰加密她的消息。然后,小明使用與他相關(guān)聯(lián)的私鑰來(lái)解密該消息。

       

      在一個(gè)實(shí)際方案中,小紅和小明使用公鑰(不對(duì)稱)加密來(lái)傳輸私(對(duì)稱)鑰,而對(duì)他們的會(huì)話的其余部分使用私鑰加密。

       

      NET中的非對(duì)稱加密算法類

      算法

      抽象算法類

      默認(rèn)實(shí)現(xiàn)類

      有效密鑰大小(位)

      默認(rèn)密鑰大小(位)

      RSA

      RSA

      RSACryptoServiceProvider

      364-16384

      1024

      DSA

      DSA

      DSACryptoServiceProvider

      364-512

      1024

       

      注意:公鑰加密算法使用固定的緩沖區(qū)大小,而私鑰加密算法使用長(zhǎng)度可變的緩沖區(qū)。公鑰算法無(wú)法像私鑰算法那樣將數(shù)據(jù)鏈接起來(lái)成為流,原因是它只可以加密少量數(shù)據(jù)。因此,不對(duì)稱操作不使用與對(duì)稱操作相同的流模型。

       

      所有的非對(duì)稱加密算法都是由AsymmetricAlgorithm類派生。

       

       

      非對(duì)稱RSA加密算法

        實(shí)際使用中很少直接用RSA類來(lái)實(shí)現(xiàn)加密算法,因?yàn)樗鼈儾捎貌贿M(jìn)行填充的原始計(jì)算。而是使用RSACryptoServiceProvider實(shí)現(xiàn)類的加密和解密方法

      public byte[] Decrypt(byte[] rgb, bool fOAEP);

      public byte[] Encrypt(byte[] rgb, bool fOAEP);

       

      創(chuàng)建個(gè)rsa算法的對(duì)象

      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

       

      我們?cè)趺传@取公鑰和私鑰信息?

      之前的對(duì)稱算法可以獲取算法的key和IV信息。

      但是非對(duì)稱算法不提供可以用于檢索密鑰信息的任何屬性!如果需要保存密鑰信息供以后使用,就只能用ToXmlString()方法輸出密鑰對(duì)的信息。

      public override string ToXmlString(bool includePrivateParameters);

      這個(gè)布爾參數(shù)如果設(shè)置為true,那么就會(huì)輸出帶私鑰的xml,如果是false,那么就只輸出帶公鑰的xml。

       

      嘗試輸出完整的密鑰對(duì)

      rsa.ToXmlString(true)

      ----------------------------完整的密鑰對(duì)信息-----------------------------

      <RSAKeyValue>

      <Modulus>yvGBq09qcWhIi+u3UHGK0EH5zav018FVGM+BPiXK23nFZeRky9HLrOH9DP5Bc7NXyBxoE0MC3YmaG68tr6nHtLhI7

      TVshAsfMX1E2BjTfLq1wHhcFwTJSvyNpwnR9NHMZsDE166XgRQ5vHkfFwBWvk7F8YVcACKp3Y6OcvAcp1s=</Modulus>

      <Exponent>AQAB</Exponent>

      <P>7+9YUu/6SFlOW4RrON/Lie+bMSmOZB/wfqj9AAdmX+n8joPQ/WLA69/CtetzIZ6KIOkD2fd8MFiFrjoHSXmpUQ==</P>

      <Q>2IgZma4hTV3EWFP3TXasajl23oRoLBeuWZldu+Q2pyeCwuBE6Mmp2aTbXauPGw3ptUAX/8pw0QyI/6i0b3wa6w==</Q>

      <DP>F4AW45Czr/BnV1lh8yEgW3NHfQo38yCZup4soZsX8N8HKKJKjvbkNHYnKRBVp35SwyRvhyLRXB7fgRAX9J9g8Q==</DP>

      <DQ>SSgCbje0rKznb2g+/37+1YzAqoFVqL//eeolDxwVkvf4Z9rZrUSlDBF0w/r4iI10znXvJc7Buv9fMfFPtPLbLQ==</DQ>

      <InverseQ>pJ37e7nw8Joy2dmnrYf5urx88NQz1TBKZF/xGReSeTiBsbkugqkoHWvX6GoWV8TL7Gx9ZRmAma/rs3YWQbk00Q==</InverseQ>

      <D>PrjbibW2wSwo183XTy54Z5sseIt/1brz8QIZALsvchu1jaNEH9ZMa7dAvWZLllXEeJ2G8QUR+qRPk+TVaug/RydliAPdf11h+7nnIoNOzk4LJtBFmNROPXTOLNwap+GJWIQM1Hd72V4kDiv1He3HUNLsLgGmUelDWekISUzrYOE=</D>

      </RSAKeyValue>

       

      上面的xml信息可以在我們需要使用的時(shí)候?qū)氲剿惴ɡ锩妗?/span>

       

      只輸出公鑰信息

      rsa.ToXmlString(false)

      ----------------------------只包含公鑰信息-----------------------------

      <RSAKeyValue>

      <Modulus>igBXA4/oLVLNP+r9jxdx1lLfqNNkSUOe0ApKql8/jmUGc/dIzSMF6bgBcvw5dBxXncYVXxrtk7

      AEilemz8PQui07M0NbJ4IeGQzRcJJNlAsQJvGWTydaoH/xLm4I0wH13RG2V9

      UjcOYPMOHBEapB4Flkst44qqclw8SVuh55OWk=</Modulus>

        <Exponent>AQAB</Exponent>

      </RSAKeyValue>

       

      一個(gè)簡(jiǎn)單的RSA例子

      RSA簡(jiǎn)單例子
      static void Main()
      {
      Byte[] StrByte = Encoding.UTF8.GetBytes("我是明文");
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      string str = RSAEncryptor(rsa.ToXmlString(false), StrByte);
      Console.WriteLine("密文:{0}", str);
      Encoding en = Encoding.UTF8;
      Console.WriteLine("明文:{0}", RSADecryptor(rsa.ToXmlString(true), Convert.FromBase64String(str), en));
      Console.Read();
      }

      public static string RSAEncryptor(string XMLKey, byte[] Str)
      {
      try
      {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.FromXmlString(XMLKey);
      return Convert.ToBase64String(rsa.Encrypt(Str, false));
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }

      public static string RSADecryptor(string XMLKey, byte[] Str, Encoding en)
      {
      try
      {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.FromXmlString(XMLKey);
      return en.GetString(rsa.Decrypt(Str, false));
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }

       

      如果給解密的RSA對(duì)象傳輸個(gè)不包含私鑰的XML,那么就會(huì)異常了,

      你可以講上面調(diào)用解密的代碼修改成下面這樣,就能得到異常了

      Console.WriteLine("明文:{0}", RSADecryptor(rsa.ToXmlString(false), Convert.FromBase64String(str), en));

       

       

      使用參數(shù)來(lái)傳遞密鑰信息

      RSAParameters

      RSACryptoServiceProvider有2個(gè)方法可以導(dǎo)出RSAParameters類型的參數(shù)對(duì)象。

      在使用加密解密算法的時(shí)候我們就只需要傳遞RSAParameters對(duì)象

       

      將上面的代碼成使用RSAParameters

       

       

      使用RSAParameters
      static void Main()
      {
      Byte[] StrByte = Encoding.UTF8.GetBytes("使用RSAParameters");
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      string str = RSAEncryptor(rsa.ExportParameters(false), StrByte);
      Console.WriteLine("密文:{0}", str);
      Encoding en = Encoding.UTF8;
      Console.WriteLine("明文:{0}", RSADecryptor(rsa.ExportParameters(true), Convert.FromBase64String(str), en));
      Console.Read();
      }

      public static string RSAEncryptor(RSAParameters KeyPar, byte[] Str)
      {
      try
      {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.ImportParameters(KeyPar);
      return Convert.ToBase64String(rsa.Encrypt(Str, false));
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }

      public static string RSADecryptor(RSAParameters KeyPar, byte[] Str, Encoding en)
      {
      try
      {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.ImportParameters(KeyPar);
      return en.GetString(rsa.Decrypt(Str, false));
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }


       

      使用容器存儲(chǔ)CSP密鑰

      之前使用的導(dǎo)出XML密鑰信息的做法并不妥當(dāng),推薦使用密鑰容器。

       

      有關(guān)密鑰容器的更多信息,請(qǐng)參見(jiàn)位于 http://www.microsoft.com/china/msdn 上的 Platform SDK 文檔中的“CryptoAPI”一節(jié)

       

      我們這里使用的密鑰容器是CspParameters類,當(dāng)我們創(chuàng)建個(gè)CspParameters對(duì)象時(shí),會(huì)生成隨機(jī)的密鑰對(duì)信息。我們只需要使用這個(gè)對(duì)象,便能方便的把密鑰信息傳遞給相關(guān)的加密解密方法。

       

      不使用密鑰容器創(chuàng)建2個(gè)不同的RSA對(duì)象

      RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider();

      string xml1 = rsa1.ToXmlString(true);

      RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider();

      string xml2 = rsa2.ToXmlString(true);

      Console.WriteLine(xml1 == xml2);

      輸出False

       

      使用密鑰容器創(chuàng)建2個(gè)不同的RSA對(duì)象

      CspParameters csp = new CspParameters();

      csp.KeyContainerName = "MyCspParameters";

      RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(csp);

      string xml1 = rsa1.ToXmlString(true);

      RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(csp);

      string xml2 = rsa2.ToXmlString(true);

      Console.WriteLine(xml1 == xml2);

      輸出True

       

      RSA加密大數(shù)據(jù)對(duì)象

      RSA算法的一個(gè)弱點(diǎn)是只能加密117字節(jié)數(shù)據(jù),前面的實(shí)例都是比較小的數(shù)據(jù)。

      所以加密大數(shù)據(jù)對(duì)象的時(shí)候我們只能使用分塊加密,講數(shù)據(jù)分成多次加密。

       

      (注意RSA加密后的Byte數(shù)組長(zhǎng)度固定為128,117和128都是在默認(rèn)密鑰大小下的規(guī)定,如果您使用的不是默認(rèn)密鑰大小,那么就會(huì)不一樣)

       

      解密的思維也是將加密后的字節(jié)數(shù)組分多次來(lái)解密,這里每次最大每次解密128字節(jié)數(shù)據(jù)。

      static void Main()
      {
      Byte[] StrByte = Encoding.UTF8.GetBytes("王祖賢(1967年1月31日出生),英文名Joey Wong,身高1.72米。出生于臺(tái)灣臺(tái)北市,祖籍安徽舒城。臺(tái)灣出道后于香港發(fā)展之電影女演員。17歲時(shí)拍攝第一部電影《今年的湖畔會(huì)很冷》并獲得金馬獎(jiǎng)三項(xiàng)提名。1987年以《倩女幽魂》一片開(kāi)始走紅于亞洲各地。2009年7月7日傳王祖賢因感情不順在加拿大削發(fā)為尼。王祖賢本人對(duì)此表示否認(rèn),王父也通過(guò)王祖賢干爹傅達(dá)仁否認(rèn)傳言。");
      Console.WriteLine(StrByte.Length);
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      string str = RSAEncryptor(rsa.ExportParameters(false), StrByte);
      Console.WriteLine("密文:{0}", str);
      Encoding en = Encoding.UTF8;
      Console.WriteLine("明文:{0}", RSADecryptor(rsa.ExportParameters(true), Convert.FromBase64String(str), en));
      Console.Read();
      }

      public static string RSAEncryptor(RSAParameters par, byte[] Str)
      {
      try
      {
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.ImportParameters(par);
      //獲取RSA最大加密的長(zhǎng)度
      Int32 KeySize = rsa.KeySize / 8;
      Int32 BlockSize = KeySize - 11;
      if (Str.Length > BlockSize)
      {
      //分配加密次數(shù)
      Int32 EncryptIndex = 0;
      if (Str.Length % BlockSize != 0)//不能整除
      {
      EncryptIndex = Str.Length / BlockSize + 1;
      }
      else
      {
      EncryptIndex = Str.Length / BlockSize;
      }
      //分配存儲(chǔ)已加密的byte數(shù)組,請(qǐng)注意下這里分配的大小
      //每次只能加密117長(zhǎng)度的數(shù)據(jù),但是每次加密117長(zhǎng)度的數(shù)據(jù)要生成128長(zhǎng)度的密文。
      Byte[] EncryptByte = new Byte[EncryptIndex * KeySize];
      for (Int32 i = 0; i < EncryptIndex; i++)
      {
      Byte[] Block = new Byte[BlockSize];
      if (i == (EncryptIndex - 1))
      {
      //最后一次加密
      Array.Copy(Str, i * BlockSize, Block, 0, Str.Length % BlockSize);
      }
      else
      {
      Array.Copy(Str, i * BlockSize, Block, 0, BlockSize);
      }
      Byte[] Block1 = rsa.Encrypt(Block, false);
      //將加密過(guò)的Byte數(shù)組保存到EncryptByte中
      Array.Copy(Block1, 0, EncryptByte, i * KeySize, KeySize);
      }
      return Convert.ToBase64String(EncryptByte);
      }
      else
      {
      byte[] b = rsa.Encrypt(Str, false);
      return Convert.ToBase64String(b);
      }
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }
      public static string RSADecryptor(RSAParameters par, byte[] Str, Encoding en)
      {
      try
      {
      Byte[] Block1;
      RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
      rsa.ImportParameters(par);
      Int32 KeySize = rsa.KeySize / 8;
      Int32 BlockSize = KeySize - 11;
      if (Str.Length == KeySize)
      {
      return en.GetString(rsa.Decrypt(Str, false));
      }
      else
      {
      //這個(gè)變量用來(lái)記錄所有解密后的Byte數(shù)組的長(zhǎng)度
      Int32 Len = 0;
      //保存每次解密后的Byte數(shù)組
      List<Byte[]> list = new List<Byte[]>();
      //計(jì)算解密需要的次數(shù)
      Int32 EncryptIndex = Str.Length / KeySize;

      for (Int32 i = 0; i < EncryptIndex; i++)
      {
      Byte[] Block = new Byte[KeySize];
      Array.Copy(Str, i * KeySize, Block, 0, KeySize);
      Block1 = rsa.Decrypt(Block, false);
      Len += Block1.Length;
      list.Add(Block1);
      }
      Byte[] EncryptByte = new Byte[Len];
      for (Int32 i = 0; i < list.Count; i++)
      {
      Array.Copy(list[i], 0, EncryptByte, i * BlockSize, BlockSize);
      }
      return en.GetString(EncryptByte);
      }
      }
      catch (CryptographicException e)
      {
      Console.WriteLine(e.Message);
      return null;
      }
      }

       


      RSA的優(yōu)點(diǎn)和缺點(diǎn)

       

      優(yōu)點(diǎn)

      1.安全性高,幾乎不會(huì)被攻破。

      缺點(diǎn)

      1.速度慢,數(shù)學(xué)原理復(fù)雜。

      2.單次加密數(shù)據(jù)小,加密大數(shù)據(jù)處理復(fù)雜

       

      作者:海不是藍(lán)

      博客:http://www.rzrgm.cn/hailan2012/

      郵箱:hailan2012@sina.com

      本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

      主站蜘蛛池模板: 泽普县| 久久亚洲精品中文字幕波多野结衣 | 日本一区二区中文字幕久久 | 色欲久久综合亚洲精品蜜桃| 内地自拍三级在线观看| 免费无码中文字幕A级毛片| 男人下部进女人下部视频| 老熟妇仑乱换频一区二区| 青青青青久久精品国产| 亚洲VA欧美VA国产综合| 久热这里只有精品视频六| 久久99国产精品久久99小说| 久久精品无码免费不卡| 18禁黄网站禁片免费观看| 色呦呦 国产精品| 亚洲熟女精品一区二区| 色综合久久久久综合体桃花网| 人妻av无码系列一区二区三区| 亚洲三区在线观看内射后入| 国产精品一区二区三区激情| 国产精品爆乳在线播放第一人称| 亚洲综合成人av在线| 亚洲中文字幕亚洲中文精| 国产仑乱无码内谢| 欧美老少配性行为| 激情综合网一区二区三区| 久久国产精品夜色| 日韩精品国产另类专区| 好硬好湿好爽好深视频| 一区二区三区国产综合在线| 国产亚洲精品中文字幕| 亚洲自偷自拍另类小说| 精品偷拍一区二区三区| 久久这里都是精品二| 精品久久久久久中文字幕202| 岳西县| 最新国产精品中文字幕| 国产成人剧情AV麻豆果冻| 国产午夜无码视频在线观看 | 丁香五月网久久综合| 日韩无矿砖一线二线卡乱|