怎樣實現(xiàn)MSMQ的消息加密_.Net教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:揭秘10項必學(xué)的.NET技術(shù)
      1、WCF (Windows Communication Foundation):雖然WCF顯然沒有WPF或SilverLight那么吸引人,但是它卻是在.NET框架下解決業(yè)務(wù)問題的基

      消息加密的工作原理

      消息應(yīng)用程序發(fā)送方對消息進(jìn)行加密后發(fā)送到目標(biāo)計算機(jī)的消息隊列中,然后由目標(biāo)計算機(jī)上的應(yīng)用程序接收消息隊列中的消息進(jìn)行解密。消息加密旨在防止在傳輸過程中有人未經(jīng)授權(quán)查看消息。

      使用消息加密會降低性能,不過這沒有使用消息驗證時性能下降得那么多。將加密的消息發(fā)送到多個不同的計算機(jī)時,由加密引起的性能下降非常明顯。但是,將多條消息發(fā)送到同一目標(biāo)計算機(jī)上時,只有發(fā)送第一條消息所花費(fèi)的時間明顯比平常發(fā)送的時間長。

      要了解消息吞吐量降低的原因,那么了解消息隊列使用的加密機(jī)制就很重要。

      在源計算機(jī)上,消息隊列執(zhí)行下列操作:

      創(chuàng)建密鑰。

      使用密鑰加密消息正文。

      使用目標(biāo)計算機(jī)的公鑰加密此密鑰。

      將加密的密鑰附加到加密的消息中。

      在目標(biāo)計算機(jī)上,消息隊列執(zhí)行下列操作:

      使用其私鑰(在密鑰對中)解密密鑰。

      使用密鑰解密消息正文。

      密鑰可用于加密和解密兩個方面,因此它們被稱為是對稱的。公鑰只能用于加密,而私鑰只能用于解密。

      由于非對稱密鑰加密比對稱的密鑰加密需要更高的開銷。因此采用類似SSL加密機(jī)制,使用非對稱加密算法加密對成加密使用的密鑰,用對稱加密算法加密需要發(fā)送的消息;解密的時候先使用非對稱解密算法解密對稱加密時使用的密鑰,然后用的得到密鑰來解密消息。

      技術(shù)實現(xiàn)

      創(chuàng)建x509證書

      X509證書用于非對稱加密

      證書的來源可以通過安裝證書服務(wù)獲取也可以通過命令生成

      生成證書的命令如下

      makecert -r -pe -n "CN=x509Signature" -b 01/01/2005 -e 01/01/2010 -sky exchange -ss my -sr localmachine

      獲取證書的方法

      static X509Certificate2 GetCertificate()

      {

      X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

      store.Open(OpenFlags.ReadOnly);

      X509Certificate2 cert = null;

      X509Certificate2Collection certCollection = store.Certificates;

      foreach (X509Certificate2 x509 in certCollection)

      {

      if (x509.Thumbprint.Equals(thumbPrint.ToUpper()))

      {

      cert = x509;

      break;

      }

      }

      if (cert == null)

      {

      store.Close();

      throw new ArgumentNullException(string.Format("The X.509 certificate (ThumbPrint: {0} ) could not be found. ", thumbPrint), "error");

      }

      store.Close();

      return cert;

      }

      使用證書實現(xiàn)非對稱加密/解密的代碼如下

      //非對稱加密密鑰

      static byte[] RSAEncrypt(byte[] enkey, X509Certificate2 Certificate)

      {

      RSACryptoServiceProvider RSA = Certificate.PublicKey.Key as RSACryptoServiceProvider;

      return RSA.Encrypt(enkey, false);

      }

      //非對成解密密鑰

      static byte[] RSADecrypt(byte[] context, X509Certificate2 Certificate)

      {

      RSACryptoServiceProvider RSA = Certificate.PrivateKey as RSACryptoServiceProvider;

      return RSA.Decrypt(context, false);

      }

      使用證書的公鑰加密,使用證書的私鑰解密

       

      加解密方法
      使用對稱加密算法進(jìn)行消息的加密和解密,代碼如下:

       

      //對稱加密消息內(nèi)容

      static byte[] Encrypt(SymmetricAlgorithm RC2, string bodystring)

      {

      MemoryStream ms = new MemoryStream();

      CryptoStream encStream = new CryptoStream(ms, RC2.CreateEncryptor(), CryptoStreamMode.Write);

      StreamWriter sw = new StreamWriter(encStream);

      sw.WriteLine(bodystring);

      sw.Close();

      encStream.Close();

      byte[] buffer = ms.ToArray();

      ms.Close();

      return buffer;

      }

      //對稱解密消息內(nèi)容

      static string Decrypt(byte[] CypherText, SymmetricAlgorithm RC2)

      {

      MemoryStream ms = new MemoryStream(CypherText);

      CryptoStream encStream = new CryptoStream(ms, RC2.CreateDecryptor(), CryptoStreamMode.Read);

      StreamReader sr = new StreamReader(encStream);

      string val = sr.ReadLine();

      sr.Close();

      encStream.Close();

      ms.Close();

      return val;

      }

       

      發(fā)送加密消息
      static void Send()

      {

      MessageQueue mq = new MessageQueue(DestinationQueue);

       

      //mq.EncryptionRequired = EncryptionRequired.Body;

      //mq.FormatName = new BinaryMessageFormatter();

      Message message = new Message();

      //采用二進(jìn)制序列化

      message.Formatter = new BinaryMessageFormatter();// new XmlMessageFormatter(new Type[] { typeof(string) });

      //獲取x509證書

      X509Certificate2 certificate = GetCertificate();

       

      //使用x509證書非對稱加密對稱加密密鑰

      RC2CryptoServiceProvider RC2 = new RC2CryptoServiceProvider();

      byte[] key=RSAEncrypt(RC2.Key, certificate);

      byte[] iv = RSAEncrypt(RC2.IV, certificate);

      byte[] extarry= new byte[256];

      key.CopyTo(extarry, 0);

      iv.CopyTo(extarry, 128);

      //保存使用非對稱加密后的對稱加密密鑰

      message.Extension = extarry;

      //message.DestinationSymmetricKey = RSAEncrypt(RC2.Key, certificate);

      //設(shè)定使用非對稱加密的證書

      //message.DigitalSignature = certificate.RawData;

      message.SenderCertificate = certificate.RawData;

      message.UseEncryption = false;

      //message.AcknowledgeType = AcknowledgeTypes.PositiveReceive | AcknowledgeTypes.PositiveArrival;

      //message.AdministrationQueue = new MessageQueue(@"thinkpad-t400\private$\myAdministrationQueue");

      //message.UseJournalQueue = true;

      message.UseDeadLetterQueue = true;

      //設(shè)定對消息體對稱加密算法

      message.EncryptionAlgorithm = EncryptionAlgorithm.Rc2;

      //message.ConnectorType = new Guid("1E9A03C5-A9B5-4BF6-B0CB-CCB313275285");

      message.Label = Guid.NewGuid().ToString();

      //生成同步加密key

      //MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

      //SHA256CryptoServiceProvider hsa = new SHA256CryptoServiceProvider();

      //byte[] keyArray = hsa.ComputeHash(System.Text.Encoding.ASCII.GetBytes(DestinationSymmetricKey));

      //message.HashAlgorithm = System.Messaging.HashAlgorithm.Sha;

      // RC2.Key = keyArray;

      //使用RC2算法進(jìn)行加密

      byte[] enarry = Encrypt(RC2, BodyString);

      string base64 = Convert.ToBase64String(enarry);

      message.Body = enarry;

      //message.SecurityContext = new SecurityContext();

      Console.WriteLine("send encrypt message \r\n" + BodyString);

      mq.Send(message, MessageQueueTransactionType.Single);

      }

       

      接收加密的消息
      static void Receive()

      {

      MessageQueue mq = new MessageQueue(DestinationQueue);

      //設(shè)定讀取消息中證書,擴(kuò)展屬性中加密過的解密密鑰

      mq.MessageReadPropertyFilter.DestinationSymmetricKey = true;

      mq.MessageReadPropertyFilter.Extension = true;

      mq.MessageReadPropertyFilter.SenderCertificate = true;

      mq.MessageReadPropertyFilter.DigitalSignature = true;

       

      Message message=mq.Receive(MessageQueueTransactionType.Single);

       

      message.Formatter = new BinaryMessageFormatter();

      //獲取證書

      byte[] cert = message.SenderCertificate;

      X509Certificate2 x509 = new X509Certificate2(cert);

      x509 = GetCertificateBySubject(x509.Subject);

      Console.WriteLine(x509.Thumbprint.ToString());

      byte[] key = new byte[128];

      byte[] iv = new byte[128];

      for(int i=0;i<message.Extension.Length;i++)

      {

      if(i<128)

      key[i] = message.Extension[i];

      else

      iv[i - 128] = message.Extension[i];

       

      }

       

      //還原對稱加密密鑰

      key = RSADecrypt(key, x509);

      iv = RSADecrypt(iv, x509);

      //解密消息

      RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();

      rc2.Key = key;

      rc2.IV = iv;

      byte[] body = message.Body as byte[];

      string bodystring= Decrypt(body, rc2);

      Console.WriteLine("receive message " + bodystring);

      }

      實施步驟

      消息接收方步驟

      消息接收方申請x509證書

      導(dǎo)出公鑰給消息發(fā)送發(fā)送放

      消息發(fā)送方步驟

      消息發(fā)送方隨機(jī)生成對稱加密的密鑰,使用該密鑰進(jìn)行對消息對稱加密。

      使用消息發(fā)送提供的證書對對稱密鑰進(jìn)行非對成加密。

      發(fā)送加密消息

      接收方收到消息

      讀取消息中的證書信息

      讀取消息中的加密的密鑰信息

      使用申請的x509證書對加密密鑰進(jìn)行解密得到密鑰

      使用對稱密鑰對加密消息進(jìn)行解密得到明文

      結(jié)束

      分享:解讀ASP.NET常用的優(yōu)化性能方法
      1. 數(shù)據(jù)庫訪問性能優(yōu)化 數(shù)據(jù)庫的連接和關(guān)閉 訪問數(shù)據(jù)庫資源需要創(chuàng)建連接、打開連接和關(guān)閉連接幾個操作。這些過程需要多次與數(shù)據(jù)庫交換信息以通過身份驗證,比較耗費(fèi)服務(wù)器資源。ASP.NET中提供了連接池(Connection Pool)改善打開和關(guān)閉數(shù)據(jù)庫對性能的影響。系

      來源:模板無憂//所屬分類:.Net教程/更新時間:2009-07-10
      相關(guān).Net教程