【WP开发】不同客户端之间传输加密数据

在上一篇文章中,曾说好本次将提供一个客户端之间传输加密数据的例子。前些天就打算写了,只是因一些人类科技无法预知的事情发生,故拖到今天。

本示例没什么技术含量,也没什么亮点,Bug林立,只不过提供给有需要的朋友娱乐娱乐一下,喜欢钻牛角尖的朋友最好别看,否则会让你一把鼻涕一把泪的。

好,废话到此为止。

因为在Windows上的RT应用程序的加/解密方法和上一篇文章中我给大家讲述的WP加解密的方法是一样的,毕竟那是共享的API。为了达到充分装逼的效果,我准备的服务器应用程序为Windows Forms应用程序,这类项目相信大家都无比熟悉了,如果你不知道Windows Forms是啥,那就没办法了。

客户端当然是WP手机端了。为了装逼而又不复杂,我的思路是这样的:

1、在WP端上选择一张.jpg靓照,通过DES算法加密,然后通过HTTP POST到服务器应用程序上。

2、作为服务器的Windows Forms应用收到文件后,用DES算法解密,并保存接收到的文件。

3、为了便于处理,加密和解密的密钥都固定。key为12345678共八个字节,iv为12345678共八个字节。

先说服务器端,因为大家都熟悉。那么,如果建立一个临时的HTTP服务器来监听连接呢。就是为了方便,所以我才不建ASP.NET应用程序,这样的小演示,就不要劳烦IIS君了。其实,在System.Net命名空间下,有一个HttpListener类,它可以通过编写代码建立一个简单的HTTP服务器,并添加绑定的URI列表,可以监听HTTP请求,然后作出处理。

在使用HttpListener前,最好调用它的静态的IsSupported属性来确认一下,你当前的系统是否能支持HTTP监听。

            if (!HttpListener.IsSupported)
            {
                MessageBox.Show("你当前的系统太破,不支持HTTP监听。");
                this.Close();
            }

通过这一检查后,说明系统是支持的,然后再实现后面的功能。这里顺便说说配置服务器地址时要注意的一些小事。

1、绑定的URI加到Prefixes集合中。

2、URI的路径可以自己安排,比如http://192.168.1.101:8080/sv/,也可以http://192.168.1.101:8080/a/b/c/,假设你的IP是192.168.1.101,不应该用localhost,因为它只有本机才能访问,实际上就是127.0.0.1。

URI必须以HTTP开头,以/结尾,尤其是结尾,不要少了/,否则会发生异常。

如果不确定我的IP呢,或者说绑定本地多个IP呢,可以这样http://+:80/rec/,80是端口号,你可以根据实际来指定。

调用Start方法开始监听,调用Stop方法停止。我这里用一个Task来循环监听连接。主要代码如下:

            this.mHttpListener.Start();
            Task backTask = new Task(WorkInBack, mHttpListener);
            backTask.Start();

            ……
        private async void WorkInBack(object obj)
        {
            HttpListener httpSvr = obj as HttpListener;
            while (httpSvr.IsListening)
            {
                HttpListenerContext context = await httpSvr.GetContextAsync();
                // 从标头中提取文件名
                string fileName = context.Request.Headers.Get("file_name");
                fileName = Path.Combine(this.docFolderPath, fileName);
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                using (FileStream outStream = File.OpenWrite(fileName))
                {
                    MemoryStream tempStream = new MemoryStream();
                    // 解密
                    byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8 };
                    byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
                    DESCryptoServiceProvider des=new DESCryptoServiceProvider();
                    CryptoStream streamCrypt = new CryptoStream(tempStream, des.CreateDecryptor(key, iv), CryptoStreamMode.Write);
                    context.Request.InputStream.CopyTo(streamCrypt);
                    //streamCrypt.Flush();
                    // 复制内存流到文件流
                    tempStream.Position = 0L;
                    tempStream.CopyTo(outStream);
                    streamCrypt.Dispose();
                    tempStream.Dispose();
                }
            }
        }

在传统.net程序中使用DES加解密相信大家都用得不少了,我就不介绍了。IsListening属性可以判断监听器是否正在工作,如果Stop了就不再接收连接请求了。

文件名是从file_name标头中获取的,这个标头是自定义的,在WP客户端发送文件时顺便加上这个标头。

下面是WP客户端的实现。

这里用到我以前说过的文件选择器。前面文章中我说过,FileOpenPicker的PickSingleFileAndContinue方法调用后,会暂时离开当前应用,等用户选择完后,会重新激活应用,并通过OnActivated方法把用户选择的文件传递进来。

        protected override void OnActivated(IActivatedEventArgs args)
        {
            if (args.Kind == ActivationKind.PickFileContinuation)
            {
                FileOpenPickerContinuationEventArgs e = (FileOpenPickerContinuationEventArgs)args;
                if (e.Files.Count > 0)
                {
                    StorageFile theFile = e.Files[0];
                    Frame root = Window.Current.Content as Frame;
                    if (root != null)
                    {
                        MainPage page=root.Content as MainPage;
                        if (page != null)
                        {
                            page.SendFile(theFile);
                        }
                    }
                }
            }
            Window.Current.Activate();
        }

SendFile方法是在MainPage页面类中公开的一个自定义方法,代码如下:

        public async void SendFile(StorageFile file)
        {
            IRandomAccessStream encryptedstream = null;
            using (IRandomAccessStream inStream = await file.OpenReadAsync())
            {
                encryptedstream = await EncryptoDataAsync(inStream);
            }
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("file_name", file.Name);
                HttpResponseMessage response = null;
                using (HttpStreamContent content = new HttpStreamContent(encryptedstream))
                {
                    response = await client.PostAsync(new Uri(txtServer.Text), content);
                }
                if (response != null && response.StatusCode == HttpStatusCode.Ok)
                {
                    // 发送成功
                }
            }

        }

HttpClient比较好的地方是它对要发送的内容可以以不同内容格式进行封装。

比如,要发字符串,就用HttpStringContent;要发送 multipart/form-data MIME数据就用HttpMultipartFormDataContent。此处,发送的是文件,应该用HttpStreamContent,以流的形式发送。

在上面代码中,EncryptoDataAsync是我定义的一个方法,作用当然是将输入的文件流加密,再存放到内存流中,并将内存流返回。代码:

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="inputStream"></param>
        /// <returns></returns>
        private async Task<IRandomAccessStream> EncryptoDataAsync(IRandomAccessStream inputStream)
        {
            byte[] bytekey = { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[] byteiv = { 1, 2, 3, 4, 5, 6, 7, 8 };
            IBuffer key = bytekey.AsBuffer();
            IBuffer iv = byteiv.AsBuffer();
            SymmetricKeyAlgorithmProvider prd = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.DesCbcPkcs7);
            // 创建密钥
            CryptographicKey crykey = prd.CreateSymmetricKey(key);
            // 加密数据
            InMemoryRandomAccessStream mms = new InMemoryRandomAccessStream();
            IBuffer orgData = null;
            using (DataReader reader = new DataReader(inputStream))
            {
                uint len=(uint)inputStream.Size;
                await reader.LoadAsync(len);
                orgData = reader.ReadBuffer(len);
            }
            IBuffer res = CryptographicEngine.Encrypt(crykey, orgData, iv);
            await mms.WriteAsync(res);
            mms.Seek(0UL);
            return mms;
        }

前面在说双向加密时,介绍过RT API中加密解密的过程。

先通过SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.DesCbcPkcs7)获得一个实例。
然后,创建CryptographicKey实例,作为加密用的key。

最后,用CryptographicEngine类来完成加密。

==============================

示例核心部分已经向大家介绍了。其余部分省略5000多个字,稍后我会把源代码打包上传。

注意在使用源码时,以管理员身份运行VS,这样HTTP服务才能监听;手机端用真机测试容易连接;要是连不上,就先把防火墙关了再试,试完了重新开启防火墙即可。

下载地址:http://files.cnblogs.com/files/tcjiaan/Sample.zip

时间: 2024-10-07 21:55:35

【WP开发】不同客户端之间传输加密数据的相关文章

WCF服务端开发和客户端引用小结

1.服务端开发(包含寄宿) 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序,可生成一个带.svc后缀名的文件.该文件与webform中的aspx文件类似,有后置代码,这些后置代码是服务接口的实现.这种方式创建的WCF服务都承载在IIS或WAS上. (2)创建WCF服务库 WCF服务库是一个类库,如前所述包含一个服务接口和服务实现,此种方式创建的WCF服务可根据

视频开发技术之文件传输

AnyChat具有缓冲区及文件传输功能,可以实现客户端与客户端之间的缓冲区和文件传输,也可以实现客户端与服务器之间的缓冲区和文件传输功能(V4.1版本新增功能). AnyChat客户端之间的缓冲区及文件传输通道有: 1.透明通道API接口:BRAC_TransBuffer: 2.透明通道扩展API接口:BRAC_TransBufferEx: 3.文件传输API接口:BRAC_TransFile: AnyChat客户端与服务器之间的缓冲区及文件传输通道有: 1.SDK Filter Data AP

使用zlib模块实现HTTP服务端与客户端实现传输数据压缩

现如今在处理http请求的时候,由于请求的资源较多,如果不启用压缩的话,那么页面请求的流量将会非常大.启用gzip压缩,在一定程度上会大大的提高页面性能. 因此这写一个使用Node.js实现在http客户端与服务端传输压缩数据的实例代码.在HTTP服务器端与HTTP客户端之间传输压缩数据时,在客户端请求头中需要使用accept-encoding字段指定服务端压缩数据时使用的压缩算法,在服务端响应头中使用content-encoding字段声明服务器端响应数据的压缩算法. 首先来看服务端代码吧,这

linux c服务器与客户端之间的文件传输

最近做了一下linux C网络方面的项目,简单的写了一下服务器于客户端之间上传,下载文件,利用并发服务器,可以实现多个客户端同时上传,下载. 写的不好,还请大神多多指教!多的不说,一切都在代码中,部分代码如下所示: /*server.c */ 服务器端 void *recvmation(void *arg) //接收客户端发送过来的信息,线程 { int my_fd = *((int *)arg); int n; while(1) { n = recv(my_fd, (struct regis

腾讯QQ的开发分客户端软件和服务器端软件

Windows客户端主要是C++ COM/ATL Q+Web 后端C++ CGI ,前端javascript和flash 望采纳 腾讯QQ使用何种开发平台? 腾讯QQ的开发分客户端软件和服务器端软件两部分. 客户端采用 Microsoft Visual C++开发: 服务器端软件采用Linux gcc开发 : 数据库采用MySql 数据库. 腾讯QQ采用标准的TCP/IP协议为通信协议. TCP/IP协议中又分为TCP协议和UDP协议,TCP协议是面向连接的协议,它比较安全.稳定,但是效率不高,

android开发新浪微博客户端 完整攻略 [新手必读]

开始接触学习android已经有3个礼拜了,一直都是对着android的sdk文档写Tutorials从Hello World到Notepad Tutorial算是初步入门了吧,刚好最近对微博感兴趣就打算开发个android版本的新浪微博客户端作为练手项目,并且以随笔的方式详细的记录开发的全过程.本人对java语言以及eclipse Ide都是初次应用基本上属于边学边用,做移动设备上的东西也是第一次,总的来说属于无基础.无经验.无天赋的纯三无人员,还请广大同学们多多给予指点. 开发第一件事情,那

通过SSH实现Windows与linux之间传输文件

Linux是非常好的开发环境,但很多时候我们希望能够在Windows上操作,通过SSH协议可以实现两者之间传输文件. 一 需要在Linux系统上安装ssh-server,有的linux系统自带了. 查看ssh是否运行的命令:ps -ef | grep ssh 安装sshu服务器端的命令:sudo apt install openssh-erver 二 下载对应的ssh  Windows版本客户端.这里我推荐putty,开源免费. 三 利用putty自带的PSFTP来上传下载文件. 连接  ope

securecrt在linux与windows之间传输文件(转)

摘自:http://blog.csdn.net/rangf/article/details/6096365 SecureCRT这款SSH客户端软件同时具备了终端仿真器和文件传输功能.比ftp命令方便多了,而且服务器不用再开FTP服务了.rz,sz是便是Linux/Unix同Windows进行ZModem文件传输的命令行工具. windows端需要支持ZModem的telnet/ssh客户端,SecureCRT就可以用SecureCRT登陆到Unix/Linux主机(telnet或ssh均可).

MMORGP大型游戏设计与开发(客户端架构 part1 of vegine)

重写有些核心接口的时候,其实遇到了许多的问题,甚至一度的想过要放弃,但是最终还是坚持了下来.在客户端提供的这些接口中,可以清晰的看到客户端所依赖的各种模块的支持,以及各自之间的一些关联.下面只是介绍了vengine(微引擎)接口的基础模块框架,所谓的接口即对象设计中常见的Interface,为一个框架提供了清晰的规范支持. VEGINE FRAMEWORK 功能实现 该接口已全部实现,具体的实例只需要继承接口封装即可.上图只为简单的模块介绍,其实每个接口都有每个接口其特别的用处,这一点会在接下的