稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密

简介:
[索引页]
[源码下载]


稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密


作者: webabcd


介绍
Silverlight 2.0 调用 WCF 服务,对客户端与服务端传输的消息做加密    
    在 Visual Studio 2008 中使用"添加服务引用"会自动生成代理类。只支持BasicHttpBinding


在线DEMO
http://webabcd.blog.51cto.com/1787395/342779


示例
clientaccesspolicy.xml
<? xml  version ="1.0"  encoding ="utf-8"  ?> 
< access-policy > 
         < cross-domain-access > 
                 < policy > 
                         < allow-from  http-request-headers ="*" > 
                                 < domain  uri ="*"  /> 
                         </ allow-from > 
                         < grant-to > 
                                 < resource  path ="/"  include-subpaths ="true"  /> 
                         </ grant-to > 
                 </ policy > 
         </ cross-domain-access > 
</ access-policy > 
<!--  
System.Net 命名空间 和 System.Net.Sockets 命名空间的跨域调用,需要在目标域的根目录下配置策略文件 
Image 控件 和 MediaElement 控件所访问的跨域地址,不受策略文件的限制 
HTTP 调用 仅支持 GET 和 POST ,只有 200(确定) 和 404(未找到) 状态代码可用 
同域:同一子域、协议和端口。不符合以上任一条件则为跨域 
Silverlight 与 HTTP/HTTPS 的所有通信均为异步 

关于策略文件详见文档 
-->
 
 
1、调用 WCF 服务
WCFService.cs(WCF 服务)
InBlock.gif using System; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Runtime.Serialization; 
InBlock.gif using System.ServiceModel; 
InBlock.gif using System.ServiceModel.Activation; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.Security.Cryptography; 
InBlock.gif using System.IO; 
InBlock.gif 
/// <summary> 
/// 提供 WCF 服务的类 
/// </summary> 
InBlock.gif[ServiceContract] 
InBlock.gif[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
InBlock.gif public  class WCFService 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// 返回指定的 User 对象(用于演示 Silverlight 调用 WCF 服务) 
InBlock.gif         /// </summary> 
InBlock.gif         /// <param name="name">名字</param> 
InBlock.gif         /// <returns></returns> 
InBlock.gif        [OperationContract] 
InBlock.gif         public User GetUser( string name) 
InBlock.gif        { 
InBlock.gif                 return  new User { Name = name, DayOfBirth =  new DateTime(1980, 2, 14) }; 
InBlock.gif        } 
InBlock.gif}
 
WCF.xaml
<UserControl x:Class="Silverlight20.Communication.WCF" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
        <StackPanel HorizontalAlignment="Left" Margin="5"> 
         
                <TextBlock x:Name="lblMsg" /> 
         
        </StackPanel> 
</UserControl>
 
WCF.xaml.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif using Silverlight20.WCFServiceReference; 
InBlock.gif using System.Threading; 
InBlock.gif using System.ServiceModel; 
InBlock.gif 
InBlock.gif namespace Silverlight20.Communication 
InBlock.gif
InBlock.gif         public partial  class WCF : UserControl 
InBlock.gif        { 
InBlock.gif                SynchronizationContext _syncContext; 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 演示 Silverlight 调用 WCF 服务 
InBlock.gif                 /// </summary> 
InBlock.gif                 public WCF() 
InBlock.gif                { 
InBlock.gif                        InitializeComponent(); 
InBlock.gif 
InBlock.gif                         // 代理的配置信息在配置文件中,UI线程上的异步调用 
InBlock.gif                        Demo(); 
InBlock.gif 
InBlock.gif                         // 代理的配置信息在程序中指定,UI线程上的异步调用 
InBlock.gif                        Demo2(); 
InBlock.gif 
InBlock.gif                         // 后台线程(非UI线程)上的异步调用) 
InBlock.gif                        Demo3(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void Demo() 
InBlock.gif                { 
InBlock.gif                         /*                            
InBlock.gif                         * 服务名Client - 系统自动生成的代理类 
InBlock.gif                         *         方法名Completed - 调用指定的方法完成后所触发的事件 
InBlock.gif                         *         方法名Async(参数1, 参数2 , object 用户标识) - 异步调用指定的方法 
InBlock.gif                         *         Abort() - 取消调用 
InBlock.gif                         */
 
InBlock.gif 
InBlock.gif                        WCFServiceClient client =  new WCFServiceClient(); 
InBlock.gif                        client.GetUserCompleted +=  new EventHandler<GetUserCompletedEventArgs>(client_GetUserCompleted); 
InBlock.gif                        client.GetUserAsync( "webabcd"); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void Demo2() 
InBlock.gif                { 
InBlock.gif                         /* 
InBlock.gif                         * 服务名Client - 其构造函数可以动态地指定代理的配置信息(Silverlight 2.0 调用 WCF 只支持 BasicHttpBinding) 
InBlock.gif                         */
 
InBlock.gif 
InBlock.gif                        WCFServiceClient client =  new WCFServiceClient( new BasicHttpBinding(),  new EndpointAddress( "http://localhost:3036/WCFService.svc")); 
InBlock.gif                        client.GetUserCompleted += new EventHandler<GetUserCompletedEventArgs>(client_GetUserCompleted); 
InBlock.gif                        client.GetUserAsync("webabcd2"); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void client_GetUserCompleted(object sender, GetUserCompletedEventArgs e) 
InBlock.gif                { 
InBlock.gif                        /* 
InBlock.gif                         * 方法名CompletedEventArgs.Error - 该异步操作期间是否发生了错误 
InBlock.gif                         * 方法名CompletedEventArgs.Result - 异步操作返回的结果。本例为 User 类型 
InBlock.gif                         * 方法名CompletedEventArgs.UserState - 用户标识 
InBlock.gif                         */
 
InBlock.gif 
InBlock.gif                        if (e.Error != null
InBlock.gif                        { 
InBlock.gif                                lblMsg.Text += e.Error.ToString() + "\r\n"
InBlock.gif                                return
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                        if (e.Cancelled != true
InBlock.gif                        { 
InBlock.gif                                OutputResult(e.Result); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                void Demo3() 
InBlock.gif                { 
InBlock.gif                        // UI 线程 
InBlock.gif                        _syncContext = SynchronizationContext.Current; 
InBlock.gif 
InBlock.gif                        /* 
InBlock.gif                         * ChannelFactory<T>.CreateChannel() - 创建 T 类型的信道 
InBlock.gif                         * 服务名.Begin方法名() - 后台线程上异步调用指定方法(最后一个参数为 代理对象) 
InBlock.gif                         */
 
InBlock.gif 
InBlock.gif                        WCFService client = new ChannelFactory<WCFService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:3036/WCFService.svc")).CreateChannel(); 
InBlock.gif                        client.BeginGetUser("webabcd3"new AsyncCallback(ResponseCallback), client); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                private void ResponseCallback(IAsyncResult result) 
InBlock.gif                { 
InBlock.gif                        WCFService client = result.AsyncState as WCFService; 
InBlock.gif 
InBlock.gif                        // 服务名.End方法名() - 获取在后台线程(非UI线程)上异步调用的结果 
InBlock.gif                        User user = client.EndGetUser(result); 
InBlock.gif 
InBlock.gif                        // 调用 UI 线程 
InBlock.gif                        _syncContext.Post(GetResponse, user); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                private void GetResponse(object state) 
InBlock.gif                { 
InBlock.gif                        OutputResult(state as User); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif 
InBlock.gif                /// <summary> 
InBlock.gif                /// 输出异步调用 WCF 服务的方法后返回的结果 
InBlock.gif                /// </summary> 
InBlock.gif                /// <param name="user"></param> 
InBlock.gif                void OutputResult(User user) 
InBlock.gif                { 
InBlock.gif                        lblMsg.Text += string.Format("姓名:{0};生日:{1}\r\n"
InBlock.gif                                user.Name, 
InBlock.gif                                user.DayOfBirth.ToString("yyyy-MM-dd")); 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
 
2、对客户端与服务端传输的消息做加密
WCFService.cs(WCF 服务)
InBlock.gif using System; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Runtime.Serialization; 
InBlock.gif using System.ServiceModel; 
InBlock.gif using System.ServiceModel.Activation; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Text; 
InBlock.gif 
InBlock.gif using System.Security.Cryptography; 
InBlock.gif using System.IO; 
InBlock.gif 
/// <summary> 
/// 提供 WCF 服务的类 
/// </summary> 
InBlock.gif[ServiceContract] 
InBlock.gif[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
InBlock.gif public  class WCFService 
InBlock.gif
InBlock.gif         /// <summary> 
InBlock.gif         /// 返回指定的 User 对象(用于演示传输信息的加密/解密) 
InBlock.gif         /// </summary> 
InBlock.gif         /// <param name="name"></param> 
InBlock.gif         /// <returns></returns> 
InBlock.gif        [OperationContract] 
InBlock.gif         public User GetUserByCryptography( string name) 
InBlock.gif        { 
InBlock.gif                 return  new User { Name = Decrypt(name), DayOfBirth =  new DateTime(1980, 2, 14) }; 
InBlock.gif        } 
InBlock.gif 
InBlock.gif         /// <summary> 
InBlock.gif         /// 解密数据 
InBlock.gif         /// </summary> 
InBlock.gif         /// <param name="input">加密后的字符串</param> 
InBlock.gif         /// <returns>加密前的字符串</returns> 
InBlock.gif         public  string Decrypt( string input) 
InBlock.gif        { 
InBlock.gif                 // 盐值(与加密时设置的值一致) 
InBlock.gif                 string saltValue =  "saltValue"
InBlock.gif                 // 密码值(与加密时设置的值一致) 
InBlock.gif                 string pwdValue =  "pwdValue"
InBlock.gif 
InBlock.gif                 byte[] encryptBytes = Convert.FromBase64String(input); 
InBlock.gif                 byte[] salt = Encoding.UTF8.GetBytes(saltValue); 
InBlock.gif 
InBlock.gif                AesManaged aes =  new AesManaged(); 
InBlock.gif 
InBlock.gif                Rfc2898DeriveBytes rfc =  new Rfc2898DeriveBytes(pwdValue, salt); 
InBlock.gif 
InBlock.gif                aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; 
InBlock.gif                aes.KeySize = aes.LegalKeySizes[0].MaxSize; 
InBlock.gif                aes.Key = rfc.GetBytes(aes.KeySize / 8); 
InBlock.gif                aes.IV = rfc.GetBytes(aes.BlockSize / 8); 
InBlock.gif 
InBlock.gif                 // 用当前的 Key 属性和初始化向量 IV 创建对称解密器对象 
InBlock.gif                ICryptoTransform decryptTransform = aes.CreateDecryptor(); 
InBlock.gif 
InBlock.gif                 // 解密后的输出流 
InBlock.gif                MemoryStream decryptStream =  new MemoryStream(); 
InBlock.gif 
InBlock.gif                 // 将解密后的目标流(decryptStream)与解密转换(decryptTransform)相连接 
InBlock.gif                CryptoStream decryptor =  new CryptoStream(decryptStream, decryptTransform, CryptoStreamMode.Write); 
InBlock.gif 
InBlock.gif                 // 将一个字节序列写入当前 CryptoStream (完成解密的过程) 
InBlock.gif                decryptor.Write(encryptBytes, 0, encryptBytes.Length); 
InBlock.gif                decryptor.Close(); 
InBlock.gif 
InBlock.gif                 // 将解密后所得到的流转换为字符串 
InBlock.gif                 byte[] decryptBytes = decryptStream.ToArray(); 
InBlock.gif                 string decryptedString = UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length); 
InBlock.gif 
InBlock.gif                 return decryptedString; 
InBlock.gif        } 
InBlock.gif
 
Cryptography.xaml
<UserControl x:Class="Silverlight20.Communication.Cryptography" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
        <StackPanel HorizontalAlignment="Left" Margin="5"> 
         
                <TextBlock x:Name="lblMsg" /> 
         
        </StackPanel> 
</UserControl>
 
Cryptography.xaml.cs
InBlock.gif using System; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.Linq; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif using Silverlight20.WCFServiceReference; 
InBlock.gif using System.Text; 
InBlock.gif using System.Security.Cryptography; 
InBlock.gif using System.IO; 
InBlock.gif 
InBlock.gif namespace Silverlight20.Communication 
InBlock.gif
InBlock.gif         public partial  class Cryptography : UserControl 
InBlock.gif        { 
InBlock.gif                 public Cryptography() 
InBlock.gif                { 
InBlock.gif                        InitializeComponent(); 
InBlock.gif 
InBlock.gif                        Demo(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void Demo() 
InBlock.gif                { 
InBlock.gif                        WCFServiceClient client =  new WCFServiceClient(); 
InBlock.gif 
InBlock.gif                        client.GetUserByCryptographyCompleted+= new EventHandler<GetUserByCryptographyCompletedEventArgs>(client_GetUserByCryptographyCompleted); 
InBlock.gif                        client.GetUserByCryptographyAsync(Encrypt( "webabcd")); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 void client_GetUserByCryptographyCompleted( object sender, GetUserByCryptographyCompletedEventArgs e) 
InBlock.gif                { 
InBlock.gif                         if (e.Error !=  null
InBlock.gif                        { 
InBlock.gif                                lblMsg.Text += e.Error.ToString() +  "\r\n"
InBlock.gif                                 return
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                         if (e.Cancelled !=  true
InBlock.gif                        { 
InBlock.gif                                lblMsg.Text +=  string.Format( "姓名:{0};生日:{1}\r\n"
InBlock.gif                                        e.Result.Name, 
InBlock.gif                                        e.Result.DayOfBirth.ToString( "yyyy-MM-dd")); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 加密数据 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <param name="input">加密前的字符串</param> 
InBlock.gif                 /// <returns>加密后的字符串</returns> 
InBlock.gif                 private  string Encrypt( string input) 
InBlock.gif                { 
InBlock.gif                         // 盐值 
InBlock.gif                         string saltValue =  "saltValue"
InBlock.gif                         // 密码值 
InBlock.gif                         string pwdValue =  "pwdValue"
InBlock.gif 
InBlock.gif                         byte[] data = UTF8Encoding.UTF8.GetBytes(input); 
InBlock.gif                         byte[] salt = UTF8Encoding.UTF8.GetBytes(saltValue); 
InBlock.gif 
InBlock.gif                         // AesManaged - 高级加密标准(AES) 对称算法的管理类 
InBlock.gif                        AesManaged aes =  new AesManaged(); 
InBlock.gif 
InBlock.gif                         // Rfc2898DeriveBytes - 通过使用基于 HMACSHA1 的伪随机数生成器,实现基于密码的密钥派生功能 (PBKDF2 - 一种基于密码的密钥派生函数) 
InBlock.gif                         // 通过 密码 和 salt 派生密钥 
InBlock.gif                        Rfc2898DeriveBytes rfc =  new Rfc2898DeriveBytes(pwdValue, salt); 
InBlock.gif 
InBlock.gif                         /* 
InBlock.gif                         * AesManaged.BlockSize - 加密操作的块大小(单位:bit) 
InBlock.gif                         * AesManaged.LegalBlockSizes - 对称算法支持的块大小(单位:bit) 
InBlock.gif                         * AesManaged.KeySize - 对称算法的密钥大小(单位:bit) 
InBlock.gif                         * AesManaged.LegalKeySizes - 对称算法支持的密钥大小(单位:bit) 
InBlock.gif                         * AesManaged.Key - 对称算法的密钥 
InBlock.gif                         * AesManaged.IV - 对称算法的密钥大小 
InBlock.gif                         * Rfc2898DeriveBytes.GetBytes(int 需要生成的伪随机密钥字节数) - 生成密钥 
InBlock.gif                         */
 
InBlock.gif 
InBlock.gif                        aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; 
InBlock.gif                        aes.KeySize = aes.LegalKeySizes[0].MaxSize; 
InBlock.gif                        aes.Key = rfc.GetBytes(aes.KeySize / 8); 
InBlock.gif                        aes.IV = rfc.GetBytes(aes.BlockSize / 8); 
InBlock.gif 
InBlock.gif                         // 用当前的 Key 属性和初始化向量 IV 创建对称加密器对象 
InBlock.gif                        ICryptoTransform encryptTransform = aes.CreateEncryptor(); 
InBlock.gif 
InBlock.gif                         // 加密后的输出流 
InBlock.gif                        MemoryStream encryptStream =  new MemoryStream(); 
InBlock.gif 
InBlock.gif                         // 将加密后的目标流(encryptStream)与加密转换(encryptTransform)相连接 
InBlock.gif                        CryptoStream encryptor =  new CryptoStream(encryptStream, encryptTransform, CryptoStreamMode.Write); 
InBlock.gif 
InBlock.gif                         // 将一个字节序列写入当前 CryptoStream (完成加密的过程) 
InBlock.gif                        encryptor.Write(data, 0, data.Length); 
InBlock.gif                        encryptor.Close(); 
InBlock.gif 
InBlock.gif                         // 将加密后所得到的流转换成字节数组,再用Base64编码将其转换为字符串 
InBlock.gif                         string encryptedString = Convert.ToBase64String(encryptStream.ToArray()); 
InBlock.gif 
InBlock.gif                         return encryptedString; 
InBlock.gif                }                 
InBlock.gif        } 
InBlock.gif}
 
 
      本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/343130,如需转载请自行联系原作者
相关文章
|
2月前
|
Linux 网络安全 数据安全/隐私保护
Linux vsFTPd服务详解——文件加密传输配置
Linux vsFTPd服务详解——文件加密传输配置
147 2
|
7月前
|
小程序 安全 网络安全
申请免费 SSL 证书为您的小程序加密通信
申请免费 SSL 证书为您的小程序加密通信
140 0
|
5天前
|
前端开发 算法 JavaScript
实现注册登录时数据的加密传输(含前后端具体代码)
实现注册登录时数据的加密传输(含前后端具体代码)
|
2月前
|
安全 小程序 Java
java实现微信服务(公众)号用户关注时,获取openid,安全模式下的加密解密实现
java实现微信服务(公众)号用户关注时,获取openid,安全模式下的加密解密实现
21 0
|
4月前
|
JSON 安全 Go
加密通信秘籍:网络安全不容忽视
加密通信秘籍:网络安全不容忽视
28 0
|
4月前
|
算法 安全 网络安全
HTTPS加密原理解析:保障通信安全的密码学算法
HTTPS加密原理解析:保障通信安全的密码学算法
58 0
|
5月前
|
数据安全/隐私保护
ACK Acknowledgement 确认 AES Advanced Encryption Standard 高级加密标准 ATM Asynchronous Transfer Mode异步传输模式
ACK Acknowledgement 确认 AES Advanced Encryption Standard 高级加密标准 ATM Asynchronous Transfer Mode异步传输模式
23 0
|
6月前
|
安全 数据安全/隐私保护
使用openssl 模拟ca进行证书的申请和颁发,并使用证书部署网站的安全连接访问,即https的加密通信
使用openssl 模拟ca进行证书的申请和颁发,并使用证书部署网站的安全连接访问,即https的加密通信
46 0
|
7月前
|
存储 数据安全/隐私保护
14.11 Socket 基于时间加密通信
在之前的代码中我们并没有对套接字进行加密,在未加密状态下我们所有的通信内容都是明文传输的,这种方式在学习时可以使用但在真正的开发环境中必须要对数据包进行加密,此处笔者将演示一种基于时间的加密方法,该加密方法的优势是数据包每次发送均不一致,但数据包内的内容是一致的,当抓包后会发现每次传输的数据包密文是随机变化的,但内容始终保持一致,也就是说两个拥有相同内容的数据被加密后,数据包密文不同,其主要运用了基于当前时间戳的通信机制。
31 0
14.11 Socket 基于时间加密通信
|
8月前
|
数据安全/隐私保护 C++ Python
Qt RSA OpenSSL C++ Qt加密解密签字通信系统窗体源码
Qt RSA OpenSSL C++ Qt加密解密签字通信系统窗体源码
130 0
Qt RSA OpenSSL C++ Qt加密解密签字通信系统窗体源码