在tcp通訊中爲了數據安全在某些情況下對數據進行加密傳輸是很有必要的,可惜的是MS並沒有爲Silverlight提供一些標準的加密功能實現.如果你想在Silverlight中使用RSA或DES這些標準的加密算法,那真的不好意思MS並沒有提供...不過我們可以使用一些基於Silverlight開源實現的加密庫,以下就是一個開源的RSA加密庫http://scrypt.codeplex.com.
RSA是一種非對稱加密算法,它提供數據加密和簽名的功能.Rsa的加解密都用不同的密鑰,所以即使你有加密的密鑰也無法對加密的數據進行解密(相對解密成本).如果想破解加密數據那必須要把別一方的密鑰破解,想分解RSA 2048位的密鑰基本是不可能的事情.下面通過簡單的例子來運RSA進行數據加密傳輸.
在編寫代碼之前先整理一下流程,假設我們需要加密提供給服務器的數據,那麼我們必須向服務獲取一個RSA的公鑰,而密鑰則保留在服務器端.客戶端只需要採用公鑰進行數據加密;服務器用私鑰進行數據解密就OK了.
以下是制定簡單的通訊協議
public class GetKey:Beetle.IMessage { public void Load(Beetle.BufferReader reader) { } public void Save(Beetle.BufferWriter writer) { } } public class GetKeyResponse:Beetle.IMessage { public string PublicKey; public void Load(Beetle.BufferReader reader) { PublicKey = reader.ReadString(); } public void Save(Beetle.BufferWriter writer) { writer.Write(PublicKey); } }
分別是獲取密鑰請求和應答
服務器端只需要根據連接創建一個新的RSA 2048加密對象,並把密鑰導出到XML中,注意導出的時候只導公鑰部分就行了
private RSACryptoServiceProvider GetRsa(TcpChannel channel) { string key = "_RSA"; RSACryptoServiceProvider result = (RSACryptoServiceProvider)channel[key]; if (result == null) { result = new RSACryptoServiceProvider(2048); channel[key] = result; } return result; } public void GetKey(TcpChannel channel, GetKey e) { GetKeyResponse response = new GetKeyResponse(); response.PublicKey = GetRsa(channel).ToXmlString(false); channel.Send(response); Console.WriteLine("{0} Get PublicKey!", channel.EndPoint); }
Silverlight在接收到公鑰數據只需要把他導入到對應的RSA對象中
public void Response(Beetle.TcpChannel channel, GetKeyResponse e) { RSACrypto.FromXmlString(e.PublicKey); Dispatcher.BeginInvoke(() => { txtStatus.Content = "獲取公鑰成功!"; cmdRegister.IsEnabled = true; }); }
導入之後就可以進行相應數據的加密工作
private void cmdRegister_Click(object sender, RoutedEventArgs e) { try { Register register = new Register(); register.UserName = RSACrypto.Encrypt(Encoding.UTF8.GetBytes(txtUserName.Text)); register.PassWord = RSACrypto.Encrypt(Encoding.UTF8.GetBytes(txtPassWord.Text)); Channel.Send(register); } catch (Exception e_) { txtStatus.Content = e_.Message; } }
服務器接收數據後進行相關解密工作
public void Register(TcpChannel channel, Register e) { Console.WriteLine("username:{0}", Smark.Core.Functions.ToString(e.UserName)); Console.WriteLine("password:{0}", Smark.Core.Functions.ToString(e.PassWord)); Console.WriteLine("username:{0}", Encoding.UTF8.GetString(GetRsa(channel).Decrypt(e.UserName,true))); Console.WriteLine("password:{0}", Encoding.UTF8.GetString(GetRsa(channel).Decrypt(e.PassWord, true))); }
解密數據對比
理解流程後使用RAS對通信數據加密是件很簡單的事情,由於RSA加密數據效率不高,所以對於大量通訊數據一般不採用RSA來處理.這個時候可以採用對稱加密來處理,但對稱加密有個缺點就是加解密鑰是一樣的,爲了保證密鑰在傳輸的過程中不易被獲取所以一般都會採用RSA對密鑰進行加密.
下載完全代碼