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

本示例没什么技术含量,也没什么亮点,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 = { , , , , , , , };
byte[] iv = { , , , , , , , };
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 > )
{
StorageFile theFile = e.Files[];
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 = { , , , , , , , };
byte[] byteiv = { , , , , , , , };
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

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

  1. 不制作证书是否能加密SQLSERVER与客户端之间传输的数据?

    不制作证书是否能加密SQLSERVER与客户端之间传输的数据? 在做实验之前请先下载network monitor抓包工具 微软官网下载:http://www.microsoft.com/en-us/ ...

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

    1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...

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

    现如今在处理http请求的时候,由于请求的资源较多,如果不启用压缩的话,那么页面请求的流量将会非常大.启用gzip压缩,在一定程度上会大大的提高页面性能. 因此这写一个使用Node.js实现在http ...

  4. 【ZYNQ-7000开发之九】使用VDMA在PL和PS之间传输视频流数据

    [ZYNQ-7000开发之九]使用VDMA在PL和PS之间传输视频流数据 原创 2016年01月14日 11:35:02 标签: VDMA / zynq / zedbaord / AXI 10384 ...

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

    Windows客户端主要是C++ COM/ATL Q+Web 后端C++ CGI ,前端javascript和flash 望采纳 腾讯QQ使用何种开发平台? 腾讯QQ的开发分客户端软件和服务器端软件两 ...

  6. Netty开发redis客户端,Netty发送redis命令,netty解析redis消息

    关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议.redis客户端,netty redis协议 ...

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

    Linux是非常好的开发环境,但很多时候我们希望能够在Windows上操作,通过SSH协议可以实现两者之间传输文件. 一 需要在Linux系统上安装ssh-server,有的linux系统自带了. 查 ...

  8. 用node-webkit 开发 PC 客户端

      7月 3 2013 导言 node-webkit 是一个很神奇的桌面客户端项目,正如这个项目的名字,这个项目是由node 和 webkit 构成,简单来说,就是你可以用HTML 5和 node 进 ...

  9. 使用GSoap开发WebService客户端与服务端

    Gsoap 编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现, 从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多. 用gsoap开发web service的大致思路 我 ...

随机推荐

  1. 16-01-25---Servlet复习笔记(01)

    Servlet ServletAPI中有4个java包    javax.servlet 包含Servlet与Servlet容器之间契约的类和接口    javax.servlet.http 包含HT ...

  2. Linux内核笔记——内存管理之slab分配器

    内核版本:linux-2.6.11 内存区和内存对象 伙伴系统是linux用于满足对不同大小块内存分配和释放请求的解决方案,它为slab分配器提供页框分配请求的实现. 如果我们需要请求具有连续物理地址 ...

  3. Codeforces Round #258 (Div. 2)

    A - Game With Sticks 题目的意思: n个水平条,m个竖直条,组成网格,每次删除交点所在的行和列,两个人轮流删除,直到最后没有交点为止,最后不能再删除的人将输掉 解题思路: 每次删除 ...

  4. 二分 题目 压缩打包 Special Judge? 不不不 当然不是

    http://noi.openjudge.cn/ch0111/ No 题目 分数 01 查找最接近的元素 10 3176 02 二分法求函数的零点 10 2181 03 矩形分割 10 1420 04 ...

  5. Python微信-- 分享接口(分享到朋友圈、朋友、空间)

    生成JS-SDK权限验证的签名 获取signature(签名)首先要获得 1.#获得jsapi_ticket 2.#获取当前页面的url #获取当前页面的url url="{}://{}{} ...

  6. AppDomain对于静态对象的独享引用

    AppDomain可以理解为一个独立的沙箱,当有独立的第静态对象在appDomain中被访问时,会在appDomain中产生独立的内存对象.比如appDomain1 appDomain2同时对 静态对 ...

  7. 用Eclipse搭建ssh框架

    问:ssh是哪三大框架,以及他们的作用是什么? 答:分别是struts,spring,hibernate. struts的作用是:是web层,其核心是mvc模式,他可以自动获取参数,自动类型转换,自动 ...

  8. webservice 小小例子

    Web Service的主要目标是跨平台的可互操作性.为了实现这一目标,Web Service 完全基于XML(可扩展标记语言).XSD(XML Schema)等独立于平台.独立于软件供应商的标准,是 ...

  9. openGL实现二维图形和三维图形

    openGL是一个强大的底层图形库,其命令最初的时候使用C语言实现的.openGL定义了一个图形程序接口,常用于制作处理三维图像,功能强大,调用方便,在图像处理十分受欢迎. 实现图形主要使用的是ope ...

  10. Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    去空格及特殊符号 s.strip().lstrip().rstrip(',') 复制字符串 #strcpy(sStr1,sStr2) sStr1 = 'strcpy' sStr2 = sStr1 sS ...