怎樣實現(xiàn)MSMQ的消息加密_.Net教程
推薦:揭秘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ù)庫對性能的影響。系
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實例(可帶附件)
- js實現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實現(xiàn)
- Asp.Net 無刷新文件上傳并顯示進(jìn)度條的實現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(連接字符串的配置及獲取)
- asp.net頁面?zhèn)髦禍y試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現(xiàn)分頁示例代碼
.Net教程Rss訂閱編程教程搜索
.Net教程推薦
- ASP.NET學(xué)習(xí)篇(4)——服務(wù)器端的控件
- 怎么在ASP.NET中使用SmtpMail發(fā)送郵件
- ASP.NET的底層的工作機(jī)制介紹
- ASP.NET中“找不到指定模塊”的解決辦法
- 解讀.Net技術(shù)開發(fā)中兩個“屬性”引起的歧異
- 用XML JSP實現(xiàn)網(wǎng)頁內(nèi)容動態(tài)顯示的方案
- asp.net2.0 URL重寫以及urlMappings問題(2)
- asp.net中使用repeater和PageDataSource搭配實現(xiàn)分頁代碼
- VS 2008和.NET 3.5 Beta2常見問題的解決方案
- 用ASP.Net實現(xiàn)在線壓縮和解壓縮
- 相關(guān)鏈接:
- 教程說明:
.Net教程-怎樣實現(xiàn)MSMQ的消息加密。