[转载]以.NET MF为依托,打造物联网时代轻量级嵌入式组态系统

mikel阅读(1044)

[转载]以.NET MF为依托,打造物联网时代轻量级嵌入式组态系统 – 叶帆工作室 – 博客园.

1 前言

在工控领域,组态软件司空见惯,国外的iFixInTouchWinCC,国内的组态王、力控、MSCG等等。组态软件的出现彻底解决了软件重复开发的问题,实现模块级复用,好处不仅仅是提高了开发效率,降低了开发周期,更大的优势的是成熟模块的复用,大大提高了系统稳定性和可靠性。

所谓组态(Configuration),就是模块化任意组合(类似积木玩具)。组态软件的主要特点有:

1)、延展性。所谓延展性,就是系统的延续和易于扩展性,用组态软件开发的系统,当现场或用户需求发生改变时(包括硬件设备或系统结构的改变),用户无需做很多修改,就可以很方便地完成系统的升级和改造;

2)、易用性。组态软件对底层功能都进行了模块级封装,对于用户,只需掌握简单的编程语言(内嵌的脚本语言,类Basic或类C语言),甚至不需要编程技术,就能很好地,通过组态配置的方式完成一个复杂系统的开发和集成;

3)、通用性。不同用户根据系统的不同,利用组态软件提供的I/O驱动(如PLC、仪表、板卡、智能模块、变频器等等驱动)、数据库和图元,就能完成一个具有动画、实时数据处理、历史数据和图表并存,且具有多媒体功能和网络功能的系统工程,不受领域或行业限制。

但是无论是基于PC平台的组态软件还是基于ARM系统的嵌入式组态软件,其组态粒度都显过大,大部分通过串口、网口、CAN等通道把个系统模块连接在一起,在一定程度上增加了系统构建的成本和代价。

而以.NET MF为依托构建的轻量级嵌入式组态软件(TinyIOs)就很好的解决了上述问题,除支持常规的串口、网口、CAN外,还支持USBWifiZigBeeSPII2C等通道,SPII2C片级总线的支持加上强大的托管代码(C#)开发能力,使嵌入式硬件系统真正的组态化、模块化成为可能,这项技术的推出,无疑为快速打造形态各异,功能不同的产品提供了最有力的支撑,完全符合新时代科技、绿色、环保的发展理念。

2 TinyIOs简介

TinyIOs,就是Tiny I/O Server的简称,在物联网、云计算时代,一切以数据为中心,不同的传感器通过不同的方式联入网络,通过云计算的方式为不同的终端用户提供服务。为了适应这种新形势的发展,加速和降低各种传感器、智能模块的入网代价,以微软成熟的.NET Micro Framework系统为基础,打造出物联网时代的轻量级嵌入式组态系统 —— TinyIOs

2.1 .NET Micro Framework简介(略)

2.2 TinyIOs系统架构

TinyIOs由三大部分构成,一是TinyIOs运行时,包含IODBIOBC、驱动引擎和策略引擎四部分;二是应用模块,包含驱动、策略和IO数据三部分;三是TinyIOs IDE环境,该工具和Microsoft Visual Studio开发工具一起共同完成驱动、策略的开发、配置及部署工作。

系统架构图(如下图所示):

TinyIOs.NET MF关系图(如下图所示)

2.3 IODB(略)

2.4 IOBC(略)

2.5驱动开发

一个驱动程序可对应一种设备,也可以对应一类设备,关键在于设备支持的协议是私有的,还是公开的,一般公开的协议,如Modbus,不同厂家的智能设备都有不同程度的支持,凡支持该协议的设备,都可以通过共同的设备驱动进行访问,唯一不同的就是访问的数据类型,起始地址,数据长度等参变量的不同而已。

2.5.1 驱动接口类

public interface IDriver

{

DeviceInfo GetDriverInfo();

int OnStart(Device device, IDeviceOperate operate);

int OnScan(Device device, IDeviceOperate operate);

int OnEnd(Device device, IDeviceOperate operate);

}

2.5.2 通信方式

public enum DeviceConnMode

{

SerialPort = 0,

Ethernet,

CAN,

USB,

SPI,

I2C,

SDIO,

Zigbee,

AD,

DA,

I,

Q,

PWM,

Other,

}

2.5.3 驱动配置信息类

public class DeviceInfo

{

public string Name;                         //32byte,驱动名称(要保证唯一)

public string Ver;                          //16byte,版本信息

public string Explain;                      //64byte,说明

public string Developer;                    //16byte,开发者

public string Date;                         //16byte,日期

public int AutoFlag;                        //自动化标志 0 – 系统为你初始化通信接口

1 – 由驱动程序本身完成通信接口初始化

public DeviceConnMode ConnMode;             //通信方式

public string Manufacturer;                 //64byte,设备制造商

public string DeviceType;                   //32byte,设备类型

//设备参数

public string PortAddrExplain;              //硬件端口名称 空为无效项

public string PortAddrValue;                //硬件端口默认值 项选择(如果有的话)用”|”

分隔开,默认项为第一个

public string PortConfigExplain;            //端口参数名称 空为无效项

public string PortConfigValue;              //端口参数默认值 项选择(如果有的话)用”|”

分隔开,默认项为第一个

public string DeviceAddrExplain;            //设备地址名称 空为无效项

public string DeviceAddrValue;              //设备地址默认值 项选择(如果有的话)用”|”

分隔开,默认项为第一个

public string DeviceConfigExplain;         //设备参数名称 空为无效项

public string DeviceConfigValue;            //设备参数默认值 项选择(如果有的话)用”|”

分隔开,默认项为第一个

//项参数

public string[] ItemExplain;                //8*32 byte,连接项名称

public string[] ItemValue;                  //8*4 byte 默认值 项选择(如果有的话)用

“|” 分隔开,默认项为第一个

}

2.5.4 驱动的执行

驱动除了按设定的扫描时间周期执行外,还可以把扫描时间设置为0,表示不会自动运行。设置为该模式的驱动,一般被策略程序直接调用而得以执行。

2.6 策略开发

可以把TinyIOs运行时想象成一个支持多任务的操作系统,这样每个策略的OnRun接口,都可以当成一个进程的Main函数,唯一不同的是,这个Main函数被调用的机制多种多样(参见策略执行模式)。

策略就是一段代码,一段标准的.NET Micro Framework程序,可以根据项目的需求充分访问.NET Micro Framework已有的开发资源(如各类库函数),编写实现任意功能的代码模块。

2.6.1 策略接口类

public interface IStrategy

{

string GetStrategyName();

int OnRun(IDeviceOperate operate, int parameter);

}

2.6.2 策略执行模式

public enum StrategyRunMode

{

None = 0,      //无动作

Loop,          //循环执行

System_Loop,   //系统循环执行

//事件驱动

Event_System_Start_Before,

Event_System_Start_After,

Event_System_End_Before,

Event_System_End_After,

Event_System_Error_Process,

Event_Driver_Scan_Before,

Event_Driver_Scan_After,

Event_Driver_Start_Before,

Event_Driver_Start_After,

Event_Driver_End_Before,

Event_Driver_End_After,

}

2.6.3 策略另类功能

策略除了按策略执行模式执行外,策略之间还可以互相调用,并且还可以直接调用指定名称的驱动程序的执行。

2.7 TinyIOs项目存储(略)

3 TinyIOs IDE简介

详情请观看视频:http://video.sina.com.cn/v/b/38583321-1804832611.html

4 TinyIOs应用实例(远程医疗系统)

5相关资源

1、官方网址

http://www.microsoft.com/netmf/default.mspx

2、官方博客

http://blogs.msdn.com/netmfteam/

3、中文博客

http://blog.csdn.net/yefanqiu

http://www.cnblogs.com/yefanqiu

4、中文论坛

http://space.cnblogs.com/group/MFSoft

http://social.msdn.microsoft.com/Forums/zh-CN/microframeworkzhchs/threads

5V4.0 SDK下载

http://www.microsoft.com/downloads/details.aspx?FamilyId=77dbfc46-14a1-4dcf-a809-eda7ccfe376b&displaylang=en

6V4.0 PortingKit(源码)下载

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=16fa5d31-a583-4c0d-af74-f4d5e235d5bc

7.NET Micro Framework低价开发板

http://item.taobao.com/item.htm?id=7117999726

[转载]UCenter 与 Asp.net 通讯

mikel阅读(1020)

[转载]UCenter 与 Asp.net 通讯 – Dozer .NET 技术博客 – 博客园.

UCenter 与 Asp.net 通讯

前言

学生在线下面有多个子站,其中包括一个Discuz论坛

那当然要充分利用强大的UCenter来实现多点登陆

UCenter和别的网站跨域通讯,那用的肯定是WebService

PHP官方封装好了,所以很容易就搞定了,但是.Net…

网上找不到任何核心的通讯手册,除非去扣那个PHP的开发手册

Google后:

UCenter 接口开发手册:这个就是官方封装过的版本,其实这个根本不能叫接口开发手册,里面介绍的都是已经封装过的PHP函数,对核心只字不提

一个项目文件:刚看到这个我很兴奋,但是按照它说的调整好后,却不能用!一开始还不懂为什么,懂得原理后才知道,它其实是个空壳

一个DLL文件:这个DLL很强大,可惜,没有例程、没有手册、没有注释,还有BUG…

但是相对来说,最后的那个DLL是最接近的,所以决定反编译之,开始研究

最后就有了Dozer编辑版~ 成功实现通讯!

来源:dozer.cnblogs.com 作者:Dozer

UCenter通讯原理

原理网上很多,我也只是知道一个皮毛,在这里就以同步登陆为例子,来讲解一下这个类库的用法

login

以上就是同步登陆的步骤,如果你已经配置好,那么只需要这3行代码

01 namespace WebApplication1
02 {
03 public partial class Default : System.Web.UI.Page
04 {
05 protected void Page_Load(object sender, EventArgs e)
06 {
07 var uc = new UCClient();
08 var user = uc.UC_User_Login("user", "password").User;
09 Response.Write(uc.UC_User_Synlogin(user.Uid));
10 }
11 }
12 }

总之,在你的网站程序中需要有2个部分

一个是UCAPI部分,需要给UCenter调用

另外一部分就是UClient部分,用于调用UCenter

这样才能在最后实现双向通讯

来源:dozer.cnblogs.com 作者:Dozer

UCenter端配置过程

按照惯例,登陆UCenter后台,然后添加应用程序

别的地方和PHP网站一样,只有一个地方,就是“应用接口文件名称”的地方

需要填写uc.ashx

这个和此类库的原理有关,后面详解

1

提交…可惜,显示通讯不成功,因为我的网站还没配置呢~

提交后再次编辑,会得到一段PHP的配置信息

01 define('UC_CONNECT', 'mySQL');
02 define('UC_DBHOST', localhost');
03 define('UC_DBUSER', 'root');
04 define('UC_DBPW', 'mySQL');
05 define('UC_DBNAME', 'uc_discuz');
06 define('UC_DBCHARSET', 'utf8');
07 define('UC_DBTABLEPRE', '`uc_discuz`.uc_');
08 define('UC_DBCONNECT', '0');
09 define('UC_KEY', 'qwertyui');
10 define('UC_API', 'http://localhost/ucenter');
11 define('UC_CHARSET', 'utf-8');
12 define('UC_IP', '127.0.0.1');
13 define('UC_APPID', '19');
14 define('UC_PPP', '20');

先留着,后面会用到~

来源:dozer.cnblogs.com 作者:Dozer

WebApplication端配置过程

第一步当然是Web.config文件

新建一个网站应用程序,并且引用这个类库

上面的配置信息是PHP用的,我们把它转换到Web.config文件中去

01 <appSettings>
02 <add key="UC_CONNECT" value="mysql"/>
03 <add key="UC_DBHOST" value="localhost"/>
04 <add key="UC_DBUSER" value="root"/>
05 <add key="UC_DBPW" value="mysql"/>
06 <add key="UC_DBNAME" value="uc_discuz"/>
07 <add key="UC_DBCHARSET" value="utf8"/>
08 <add key="UC_APPIDUC_DBTABLEPRE" value="`uc_discuz`.uc_"/>
09 <add key="UC_DBCONNECT" value="0"/>
10 <add key="UC_KEY" value="qwertyui"/>
11 <add key="UC_API" value="http://localhost/ucenter"/>
12 <add key="UC_CHARSET" value="utf-8"/>
13 <add key="UC_IP" value="127.0.0.1"/>
14 <add key="UC_APPID" value="19"/>
15 <add key="UC_PPP" value="20"/>
16 </appSettings>

来源:dozer.cnblogs.com 作者:Dozer

第二步是建立UCAPI,供UCenter调用(这步完成后UCenter中会显示通讯正常)

1、新建一个叫API的文件

2、在里面建立一个新文件uc.ashx(不要建立.aspx)

3、打开这个uc.ashx文件,本来它继承于IHttpHandler,我们把它修改一下,让它继承于FS.API.UCenter.UCAPI.UCAPIBase

4、实现一下这个抽象类的函数(利用VS的代码自动完成功能)

5、接下来你就可以在这里写一些逻辑代码了

比如,当有人在别的站同步登陆后,会通知你的站点

然后会调用 Synlogin 函数,这时候,你就需要在这个函数里写一些代码

例如:写cookie之类的

Q:UCenter为什么不直接写Cookie,子站读Cookie?

A:UCenter实现的是跨域登陆,所以每个子站的Cookie是分开的,需要自己实现!

好了,完成这步后打开UCenter,你会发现:通讯成功!

UCenter测试通讯成功仅仅是调用了一个test函数,只要上述配置没写错,那就会显示通讯成功!但是它还不能实现任何功能,需要把上面的那些函数完善~

来源:dozer.cnblogs.com 作者:Dozer

第三步是在网站中调用UCenter的接口了

这个超级简单,其实“UCenter通讯原理”那部分代码

为什么要Respon.Write这段东西?

这和UCenter同步登陆原理有关,向UCenter传递信息,告诉它要同步登陆后,它不会自己通知别的子站,而是返回一段JS,需要你的网站调用这段JS,然后通知各个子站

OK了~所有配置完成~

来源:dozer.cnblogs.com 作者:Dozer

我对原来的那个DLL做了什么?

1、原来的DLL编码部分有几个严重的问题,导致编码错误,无法提交表单

2、原来的DLL估计是很久以前写的,里面序列化和反序列化的时候,规则和现在UCenter的规则不同,我根据现在的规则,修改了一下

3、修复别的一些小BUG

来源:dozer.cnblogs.com 作者:Dozer

类库下载&示例代码

代码的原始作者找不到了,遵循开源精神

另外不保证目前代码全部正确,我只是测试了几个函数

直接公布源代码:源代码

[转载]详解ASP.NET的最新安全漏洞,Padding Oracle攻击原理及其他

mikel阅读(908)

[转载]详解ASP.NET的最新安全漏洞,Padding Oracle攻击原理及其他 – 好记性不如烂键盘 – 博客园.

微软在9月17号中午正式对外公布了ASP.NET平台下的安全漏洞,即Microsoft Security Advisory (2416728)

SecurityFocus上已将此漏洞定义成了”Design Error”,那么微软一开始的设计就是错误的,为什么这么说呢?且待我们慢慢来分析。

昨天在园友的一篇博文:对ASP.NET的最新安全漏洞进一步跟进说明中也看到了对此问题的详细追踪,但上午也只是粗粗浏览,下午细看时总觉文中有些地方略显含糊,所以晚上也就顺带查了些资料,略有所得,不敢独享,遂成此文!

微软的态度

查看了许多微软官方的说明文档,总觉得这位大姑娘犯了错后总是显得扭扭捏捏,遮遮掩掩,当然对于这个比较大的安全漏洞,不管是出于商业角度的考虑还是对现有.NET架构网站的保护,我们都暂且不去谈论它,但我想攻防该有的一条策略就是:知己知彼,百战不殆!

首先,比较长的一篇文章就是ScottGu的这篇:Important: ASP.NET Security Vulnerability

在这篇文章中,其主要谈及了此漏洞的影响,简单提及了一下此漏洞产生的原因,下面就是微软教科书式的解决方案了。

这个解决方案有两个注意点:

1:公布了一段vbs,没细看,我想应该是一段检测web.config文件是否添加了customErrors节及是否配置正确的代码;

2:在错误页面中添加的一段代码,我先贴出来,看了下面的分析,我想你就该理解那段代码什么意思了。

1 void Page_Load()
2 {
3 byte[] delay = new byte[1];
4 RandomNumberGenerator prng = new RNGCryptoServiceProvider();
5 prng.GetBytes(delay);
6 Thread.Sleep((int)delay[0]);
7 IDisposable disposable = prng as IDisposable;
8 if (disposable != null) { disposable.Dispose(); }
9 }

当然,在这里你还可以看到一些类官方的讨论。

什么叫Padding Oracle

在ScottGu的文章中也提到了Padding Oracle,”……, there is a vulnerability in ASP.NET which acts as a padding oracle“。

首先得承认,padding和Oracle的确太迷惑人了,css+数据库,还挺挑战想象力的。

本人也想不出太好的中文翻译,就直译成了”附加断言”(oracle: 神谕、预言),还望各位指正。

好了,我们来看看Padding Oracle到底是什么。

在ASP.NET中设计ViewState等加密字符串时,在加密算法中,当提交一个文本(ciphertext)去加密后,加密函数将返回是否成功,如返回valid或invalid。

那 么攻击者使用不同的值去提交,并捕获返回的值,对每次返回的值进行分析,再纠正,重新提交,就这样解密出原文。那么需要多少次可以解密出到明文呢?答案 是:128*N,N是这段密文的字节数,所以也就有了博友辰文章中提到的: 这个过程100%成功而且只需要30分钟。(当然,不会是100%成功的!)

原文是这样的:

The attack works under the assumption that the attackers can intercept padded messages encrypted in CBC mode, and have access to the aforementioned padding oracle. The result is that attackers can recover the plaintext corresponding to any block of ciphertext using an average of 128 * b oracle calls, where b is the number of bytes in a block.

理解有失偏颇的,提醒下。

那么在博友辰的文章中还提到了:这个问题不仅仅存在于asp.net,而且还有java等。

这个背景在于:在隐藏字段(如ViewState),cookies,请求参数中,当加密成BASE64字符串时都涉及到这个漏洞,而在一些Java框架,如JavaServer Face中也设计了ViewState的东西,所以才有了上面的结论。

如何攻击

其实此漏洞的利用在2002年的Eurocrypt会议中已经被提及过了,可以去BlackHat网站下载PDF查看,本人上文的许多分析也提炼自此文档。

Then we decode each Base64 string found. If the result looks random, and its length is a multiple of common block cipher sizes, i.e. 8, 16 or 32 bytes, then there’s a good chance that it is a ciphertext. We also look for common separators, i.e. –, | or :, which are often used to separate IV, ciphertext, or MAC. Then we replace a byte in the last block of the ciphertext by a random value, then send it back to the target, and see what changes in the response. If there is an error message, then there’s a high chance that this is a Padding Oracle.

此段英文就比较简单了,也很明了地说明了测试是否可破解的方法。

每次替换掉最后一个字节,并将新拼接的字符串提交加密,再记录返回结果,如果可以,那么再进一步解密出原文。

到这里,我们大概对此漏洞有了一个清晰的认识,欲深入分析请查看上面的PDF文档。

再回过来看ScottGu公布的解决方案,我的猜想是:

添加错误配置节,当攻击者第一次尝试破解时,被配置节强制跳转到错误页面,在错误页面中,如果发现提交过来的构造密码种子(我理解成了种子 🙂 )为1,那么就将其对象强行Dispose掉,那么攻击者也就没法继续下去了。

小结

那么微软将如何去修复此漏洞呢,修改加密机制,还是……,持续关注。

好了,我的分析就到这里,也很晚了,文章中欠妥的地方,欢迎拍砖,一起再讨论下!

[转载]ASP.net MVC、Extjs多级目录(理论上可以无限级、非递归)treepanel显示和数据库(多级目录)存储结构的设计(上篇)

mikel阅读(1134)

[转载]ASP.net MVC、Extjs多级目录(理论上可以无限级、非递归)treepanel显示和数据库(多级目录)存储结构的设计(上篇) – 夜雨瞳 – 博客园.

1、数据库(多级目录)存储结构的设计:

1.1、表设计

1.2、数据显示及相关信息:

升序:

select C.tre_parent,B.tre_name as tre_parentname,C.tre_children as tre_children,A.tre_name as tre_childrenname,C.tre_children as children from treetable A,treetable B,treestruct C where A.tre_id=C.tre_children and B.tre_id=C.tre_parent order by C.tre_parent asc

降序:

select C.tre_parent,B.tre_name as tre_parentname,C.tre_children as tre_children,A.tre_name as tre_childrenname,C.tre_children as children from treetable A,treetable B,treestruct C where A.tre_id=C.tre_children and B.tre_id=C.tre_parent order by C.tre_parent desc

2、多级目录思想的大概模型:

3、显示运行效果:

4、性能上分析:

5、总结:

个人觉得这个treepanel的优点:灵活运用它的数据库设计。

当然,可能这样子的多级目录在很多项目开发上并不一定用得上。不过可以参考一下的,毕竟思想上的交流是互动的。数据库的表设计使这 多级目录上的增删除改有很大意义和灵活性。

6、以下是相关配置和使用的环境:

win7系统

vs2008 sp1

SQL2005

.NET FrameWork3.5

extjs3.2版本

7、下载相关

因为源代码没有加入Extjs所以这部分添加麻烦读者自己到它们的官方网站下载了。

Extjs官方下载包:http://www.sencha.com/products/js/

源代码下载包:http://files.cnblogs.com/yongfeng/TreePanel_First.rar

[转载]对ASP.NET的最新安全漏洞进一步跟进说明

mikel阅读(933)

[转载]对ASP.NET的最新安全漏洞进一步跟进说明 – 美丽人生 – 博客园.

今天上博客园,看见了关于ASP.NET的安全漏洞,内容大致是:黑客可以下载ASP.NET网站的核心文件(WEB.CONFIG),我估计还可以下载任意文件,例如数据库。

这个BUG基本上是致命的,可是博客园的描述却非常的少,我看了半天也没有明白什么意思,如何攻击,于是挖掘下去。现在把一些明细写出来。

微软原文:

http://weblogs.asp.net/scottgu/archive/2010/09/18/important-asp-net-security-vulnerability.aspx

黑客如何发起攻击:

代码

To understand how this vulnerability works, you need to know about cryptographic oracles. An oracle in the context of cryptography is a system which provides hints as you ask it questions. In this case, there is a vulnerability in ASP.NET which acts as a padding oracle. This allows an attacker to send cipher text to the web server and learn if it was decrypted properly by examining which error code was returned by the web server.  By making many such requests (and watching what errors are returned) the attacker can learn enough to successfully decrypt the rest of the cipher text.

大致意思是关于 cryptographic oracle. 黑客通过不断重复发送信息,检测返回的错误信息,然后了解加密算法,最后实现攻击。可是这段话还是没有明白,于是继续搜索:

http://visualstudiomagazine.com/articles/2010/09/14/aspnet-security-hack.aspx

这篇文章说明了大致的攻击流程。由于这个问题影响非常大,我就不翻译中文了,只是简单概述一下:

代码

they can repeatedly modify an ASP.NET Forms Authentication cookie encrypted using AES and, by examining the errors returned, determine the Machine Key used to encrypt the cookie. The process is claimed to be 100 percent reliable and takes between 30 and 50 minutes for any site.

2个研究员发现,通过一个工具,能够 修改被AES加密过的 ASP.NET窗体验证cookie;然后检查返回错误信息;获取Machine Key。这个过程100%成功而且只需要30分钟。

代码

Once the Machine Key is determined, attackers can create bogus forms authentication cookies. If site designers have chosen the option to embed role information in the security cookie, then attackers could arbitrarily assign themselves to administrator roles. This exposure also affects other membership provider features, spoofing protection on the ViewState, and encrypted information that might be stored in cookies or otherwise be made available at the client.

一 旦machine key被破解出来了,黑客就能够模拟出验证 cookie。如果网站设计者启动了选项,让安全信息放入 security cookie,那么攻击者就能够获取了 管理员权限。 包含的影响范围包括:membership provider, viewstate, 保存在security cookie里面的所有信息。

代码

While the exposure is both wide and immediate, the fix is simple. The hack exploits a bug in .NETs implementation of AES encryption. The solution is to switch to one of the other encryption mechanisms — to 3DES, for instance. Since encryption for the membership and roles providers is handled by ASP.NET, no modification of existing code should be required for Forms Authentication.

这个bug源于AES加密算法中的一个bug。因此解决方案就是:使用DES(后来被验证是错误的解决方案)。

第一部分小结

——————–

问题的关键字包括:

security cookie,  ASP.NET Forms Authentication cookie, Machine Key,role information in the security cookie.

大概意思就是,启动了asp.net的验证,并且启动了使用AES加密算法保存敏感信息在验证框架的cookie中后,黑客能够获取machinekey,然后获得管理员权限。

现在问题就是,具体是asp.net中什么操作、部署、框架会受到这个影响。于是我进一步搜索。

攻击方式:padded oracle attack

—————————————

文章下载地址:http://usenix.org/events/woot10/tech/full_papers/Rizzo.pdf

具体我没有太明白,也不知道和oracle是什么关系。不过有个回复说的比较详细:

代码

Before worrying too much, go to http://usenix.org/events/woot10/tech/full_papers/Rizzo.pdf and read the original paper from Rizzo and Duong (May 25th, 2010). The “padded oracle attack” relies on a chaining block cypher (common) but also requires the “oracle”. As some have correctly pointed out above, we need to have ASP.NET (or Java since this is not unique to .NET) return the padding error exception. Without that information, the exploit doesn’t work. By default, this exception information is not reported by ASP.NET and this is configurable behavior for Java. If you go to the aforementioned link, I think you’ll find more interesting reading related to cracking CAPTCHA using this exploit. However, that too requires cooperation from the web site. It’s great learning about exploits and even a little fun but the media sure scares a lot of people (and scares up a lot of clicks) by providing this hyperbole. One guy above said he was happy he used Java. Read the PDF above and you will find Rizzo and Duong found the problem with Java (JSF but also Ruby on Rails) and then turned to see if the same exploit would work with ASP.NET. Technically, it is an exploit but if it doesn’t happen with properly configured servers (or the default ASP.NET configuration), it’s much ado about nothing.

大致意思是,这个问题不仅仅存在在asp.net,而且还有java等。技术上,如果使用了asp.net的默认配置,是不需要担心的(所谓默认配置,就是新建一个asp.net项目的配置,没有做任何修改)。

窗体验证:Asp.net Form Authentication:

————————————————–

http://www.codeproject.com/KB/aspnet/Forms_Auth_Internals.aspx

这次受影响的,主要是因为启动了asp.net的权限框架,就是这个所谓的窗体验证。 这个窗体验证的原理在上面的连接给出了。

全文小结

————————————

浏览了很多页面,浪费了1个小时,终于有点头绪。

问题在于如果用户使用了微软提供的窗体验证框架,就会出现安全漏洞,被黑客破解了保存安全信息的算法(machine key), 然后获取了管理员权限,下载服务器的文件。

如果整个权限框架是自己写的,那么就不需要担心了。

[转载]ASP.NET 惊爆新安全漏洞 攻击者可访问任意文件

mikel阅读(894)

[转载]ASP.NET 惊爆新安全漏洞 攻击者可访问任意文件 – 思想的思想 – 博客园.

微软安全响应中心今天中午发布最新安全预警, 提醒广大ASP.NET用户防范一处新安全漏洞. 攻击者可利用存在于ASP.NET加密模块的一处最新漏洞访问到包括web.config在内的任何文件. 此漏洞存在于ASP.NET所有已发布的版本中, 其影响程度不容小视. 目前尚无补丁发布. 请广大开发和维护人员加强防范. 据悉, ASP.Net 加密模块中新公开的漏洞可使攻击者解密并篡改任意加密数据。 如果 ASP.Net 应用程序使用的是 ASP.Net 3.5 SP1 或更高版本,攻击者可以使用此加密漏洞请求 ASP.Net 应用程序中的任意文件的内容。 网络上一些已流传开的攻击案例显示出攻击者可以利用该加密漏洞获取 web.config 文件的内容。 实际上一旦攻击者获取了web应用程序worker process的访问权限, 他即有权访问的应用程序中的任意文件。

有关该漏洞的详细信息, 请访问:  http://www.microsoft.com/technet/security/advisory/2416728.mspx

[转载]ASP.NET MVC:通过 FileResult 向浏览器发送文件

mikel阅读(1000)

[转载]ASP.NET MVC:通过 FileResult 向浏览器发送文件 – 鹤冲天 – 博客园.

在 Controller 中我们可以使用 FileResult 向客户端发送文件。

FileResult

FileResult

FileResult 是一个抽象类,继承自 ActionResult。在 System.Web.Mvc.dll 中,它有如上三个子类,分别以不同的方式向客户端发送文件。

在实际使用中我们通常不需要直接实例化一个 FileResult 的子类,因为 Controller 类已经提供了六个 File 方法来简化我们的操作:

protected internal FilePathResult File(string fileName, string contentType);
protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName);
protected internal FileContentResult File(byte[] fileContents, string contentType);
protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName);
protected internal FileStreamResult File(Stream fileStream, string contentType);
protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName);

FilePathResult

FilePathResult 直接将磁盘上的文件发送至浏览器:

1. 最简单的方式

public ActionResult FilePathDownload1()
{
    var path = Server.MapPath("~/Files/鹤冲天.zip");
    return File(path, "application/x-zip-compressed");
}

第一个参数指定文件路径,第二个参数指定文件的 MIME 类型。

用户点击浏览器上的下载链接后,会调出下载窗口:

FilePathDownload1

大家应该注意到,文件名称会变成 Download1.zip,默认成了 Action 的名字。我们使用 File 方法的第二个重载来解决文件名的问题:

2. 指定 fileDownloadName

public ActionResult FilePathDownload2()
{
    var path = Server.MapPath("~/Files/鹤冲天.zip"); 
    return File("g:\\鹤冲天.zip", "application/x-zip-compressed", "crane.zip");
}

public ActionResult FilePathDownload3()
{
    var path = Server.MapPath("~/Files/鹤冲天.zip"); 
    var name = Path.GetFileName(path);
    return File(path, "application/x-zip-compressed", name);
}

我们可以通过给 fileDownloadName 参数传值来指定文件名,fileDownloadName 不必和磁盘上的文件名一样。下载提示窗口分别如下:

FilePathDownload2

FilePathDownload3

FilePathDownload2 没问题,FilePathDownload3 还是默认为了 Action 的名字。原因是 fileDownloadName 将作为 URL 的一部分,只能包含 ASCII 码。我们把 FilePathDownload3 改进一下:

3. 对 fileDownloadName 进行 Url 编码

public ActionResult FilePathDownload4()
{
    var path = Server.MapPath("~/Files/鹤冲天.zip");
    var name = Path.GetFileName(path);
    return File(path, "application/x-zip-compressed", Url.Encode(name));
}

再试下,下载窗口如下:

FilePathDownload4

好了,没问题了。上面代码中 Url.Encode(…),也可使用 HttpUtility.UrlEncode(…),前者在内部调用后者。

我们再来看 FileContentResult.

FileContentResult

FileContentResult 可以直接将 byte[] 以文件形式发送至浏览器(而不用创建临时文件)。参考代码如下:

public ActionResult FileContentDownload1()
{
    byte[] data = Encoding.UTF8.GetBytes("欢迎访问 鹤冲天 的博客 http://www.cnblogs.com/ldp615/");
    return File(data, "text/plain", "welcome.txt");
}

点击后下载链接后,弹出提示窗口如下:

FileContentDownload1

FileStreamResult

想给 FileStreamResult 找一个恰当的例子是不太容易的,毕竟 Http Response 中已经包含了一个输出流,如果要动态生成文件的话,可以直接向这个输出流中写入数据,效率还高。当然,我们不会在 Controller 中直接向 Response 的 OutputStream 写入数据,这样做是不符合MVC的,我们应该把这个操作封装成一个 ActionResult。

不过仔细想想,用途还是有的,比如服务器上有个压缩(或加密)文件,需要解压(或解密)后发送给用户。

1. 解压(或解密)

演示代码如下,解压使用 ICSharpCode.SharpZipLib.dll:

public ActionResult FileStreamDownload1()
{
    var path = Server.MapPath("~/Files/鹤冲天.zip");
    var fileStream = new FileStream(path, FileMode.Open);
    var zipInputStream = new ZipInputStream(fileStream);
    var entry = zipInputStream.GetNextEntry();
    return File(zipInputStream, "application/pdf", Url.Encode(entry.Name));
}

简单起见,假定压缩文件中只有一个文件,且是 pdf 格式的。鹤冲天.zip 如下:

FileStreamDownload1

点击后弹出下载提示窗口如下:

FileStreamDownload1-2

2. 转发(或盗链)

FileStreamResult 的另一种用途是将其它网站上的文件作为本站文件下载(其实就是盗链):

public ActionResult FileStreamDownload1()
{
    var stream = new WebClient().OpenRead("http://files.cnblogs.com/ldp615/Mvc_TextBoxFor.rar");
    return File(stream, "application/x-zip-compressed", "Mvc_TextBoxFor.rar");
}

看下面提示窗口,来源还是 localhost:

FileStreamDownload2

——————-

[转载]Web 2.0应用客户端性能问题十大根源

mikel阅读(992)

[转载]Web 2.0应用客户端性能问题十大根源 – 心 涯 – 博客园.

Web 2.0应用的推广为用户带来了全新的体验,同时也让开发人员更加关注客户端性能问题。最近,资深Web性能诊断专家、知名工具dynatrace的创始人之一Andreas Grabner根据自己的工作经验,总结了Web 2.0应用客户端性能问题十大根源,InfoQ中文站将这十个问题做了概括整理,供Web开发人员借鉴和思考。

1. IE中的CSS选择器(selector)运行缓慢

Web开发人员通常使用JavaScript框架(如JQuery)提供的CSS选择器来实现查找功能,如var element = $(“.shoppingcart”),但是IE 6和7没有提供这种查找方法的原生实现。所以,JavaScript框架不得不通过遍历整个DOM树来达到目的。这种方式花费的时间比在其他浏览器中的消 耗要多得多,而且严重依赖于DOM树的规模。IE 8对CSS查找提供了较好的支持,所以Web人员最好升级相应的JavaScript框架版本以利用这些新特性。

2.针对相同对象重复进行CSS查找

正如第一点所说,单个CSS查找代价高昂,在这种情况下,如果还要对相同的对象进行多次重复查找,那性能问题就可想而知了。下图是一个典型的Web页面中CSS查找功能调用统计结果:

dynaTrace analysis how often a CSS Selector got executed on a single page

(引自dynatrace博客,中间一列为查找函数总执行时间,单位毫秒,最后一列为函数调用次数)

对于这种问题,Andreas Grabner建议将第一次查找的结果保存到变量中,在以后需要的时候重用即可,不必再重复进行查找。

3.XHR调用太多

JavaScript和XmlHttpRequest是AJAX技术的基础,很多JavaScript框架都提供了非常方便的使用方法,Web开发人员会充分利用其异步通信优势来实现诸如分页加载等效果,避免对整个页面的操作。

Andreas Grabner根据自己的经验指出,他发现这种方式被滥用了——过多的信息通过过多的调用来动态访问。例如,在一个显示10种商品的页面中,开发人员可能 想分别加载每种商品的详细信息。这意味着,你需要和服务器端进行10次交流才能得到全部信息,也会对后台系统产生压力。他建议,在这种情况下,把10次调 用合并成1次来减少通信压力。

4.代价高昂的DOM操作

操作DOM是网页交互性的必要技术。拿添加DOM元素来说,存在多种实现方式,每种方式因为不同的浏览器类型和元素数量大小带来的性能影响也各不相同。建议大家仔细分析比较不同的方法,采用适合自身情况的技术。

5.JavaScript文件过多

Andreas Grabner说,对于一个典型的网站来说,存在超过40个单独的JavaScript文件并不少见。他指出,JavaScript文件过多带来两个问 题:一是浏览器在加载这些文件时需要通过JavaScript引擎切换上下文运行环境,二是因为下载文件而带来额外的网络通信。解决方法是:减少 JavaScript文件数量!

6.DOM规模庞大

DOM规模对页面性能影响很大,具体表现在:

  • 占用的内存
  • 从根节点到子节点的style变化所花费的开销
  • IE中CSS查找的性能问题
  • DOM遍历操作的性能问题

所以,警惕你的DOM树!

7.事件处理函数绑定过多

对于Web开发人员来说,绑定事件处理函数是日常工作之一。Andreas Grabner提醒大家关注其对性能的影响:

  • 绑定操作本身消耗时间(如查找对象、注册事件管理器等)。
  • 当事件被触发时,事件管理器需要查找注册该事件的元素,并调用正确的事件处理函数。
  • 在切换页面时,要记住对事件解绑,避免DOM相关的内存泄露问题。

8.外部服务执行缓慢

很多网页都嵌入了外部内容(如广告栏等)或者调用外部服务,Web开发人员通常需要在页面中包含由第三方提供商发布的JavaScript文件,而通常这些文件中就存在前面所提到的性能问题,我们需要擦亮眼睛,如果有问题要反馈给第三方供应商让其修改优化。

9.滥用视觉效果

很多JavaScript框架都提供了绚丽的视觉特效,如动态弹出表单等,一些方法在示例代码中运行良好,但是在实际的页面中特别是DOM 规模较大时表现不尽人意。Andreas Grabner建议Web开发人员在引入视觉效果时关注其对浏览器CPU、渲染引擎和整个网站性能的负面影响。

10.日志和监控粒度过细

现在存在很多优秀的日志和监控工具,但是如果把粒度设得太细(如记录每次鼠标移动的详情),信息的收集过程会对JavaScript引擎和网络产生额外的负担。

Web 2.0应用客户端性能问题十大根源向大家介绍完了,原文作者Andreas Grabner不仅是Web性能诊断工具dynatrace的创始人之一,而且参与了许多企业级Web应用的性能优化项目,他总结的这些问题相信会对国内Web开发人员带来一定的启示。

POST:http://www.infoq.com/cn/news/2010/08/web-performance-root

[转载]JavaScript制作flash文件进度条

mikel阅读(1098)

[转载]js制作flash文件进度条 – 郝国微 – 博客园.

演示地址:好游戏网 中的任何一个游戏

前几天在做一个flash游戏网站时遇到这样一个问题,有时一个游戏还没加载完,游戏就可以开始了,玩着玩着就加载不出来了。于是想到了做一个flash游戏的加载进度条一下是js代码:

var ubType = (navigator.userAgent.indexOf(“MSIE”) > 0);//是否是ie浏览器
var timer;//时钟

//根据id获得对象

function $(idValue){
return document.getElementById(idValue);
}

function load(swfUrl) {
if (ubType)
objrUrl.movie = swfUrl;//ie设置param的movie
else
$(“emSrc”).src = swfUrl;//火狐设置embed的src
timer = setInterval(“loading()”, 1000);//一秒钟执行一次更新加载状态
}
function loading() {

var divIng = $(“divBoolar”);进度条内实际进度
var tmeValue = 0;

//获取加载进度
if (ubType) {//判断是否IE浏览器
tempValue = objrUrl.PercentLoaded();
}
else {
tempValue = document.embeds[“emSrc”].PercentLoaded();
}

divIng.style.width = tempValue + “%”;//用内div的长度的百分比作为可视的实际进度
divIng.innerHTML = tempValue + “%”;//显示进度值
if (tempValue == 100) {//如果已经加载完
$(“objrUrl”).style.visibility = “visible”;//显示游戏
$(“objrUrl”).style.height=”400px”;//设置游戏高度
if(!ubType){
$(“emSrc”).style.visibility = “visible”;
$(“emSrc”).style.height=”400px”;
}
$(“imgLoad”).style.display = “none”;//遮盖图片消失
clearInterval(timer);//清除时钟
}
}

[转载]Jquery读取.Net WebService Json数据

mikel阅读(1115)

[转载]Jquery读取.Net WebService Json数据 – 灵动生活 – 博客园.

鉴于上篇文章中 提到的Json优点:易读性、可扩展性和操作方便,接下来我们实现一个简单的例子Demo,场景是:查询商品信息;实现过程:Web程序通过JQuery 调用WebService,Web Service返回Json对象,成功调用后,对返回的JSon结果进行处理,下面我们看一下具体实现过程:

1、 首先创建一个Aap.net web 应用程序,如下图:

2、 添加实体类Product.cs到工程中,并且序列化,代码如下

[Serializable]

public class Product

{

public long ProductId { get; set; }

public string ProductName { get; set; }

public decimal Price { get; set; }

public int Stock { get; set; }

}

3、 添加数据类ProductData.cs类到工程中,此类主要完成数据的查询操作,代码如下所示:

public class ProductData

{

private List<Product> productList = new List<Product>()

{

new Product(){ProductId=1,ProductName=”笔记本”, Price=10000M, Stock=10},

new Product(){ProductId=2,ProductName=”格子绒长袖衬衫”, Price=90M, Stock=20},

new Product(){ProductId=3,ProductName=”纯棉长袖T恤”, Price=99M, Stock=40},

new Product(){ProductId=4,ProductName=”炫彩T恤”, Price=67M, Stock=30},

new Product(){ProductId=5,ProductName=”直筒裤男牛仔裤”, Price=100M, Stock=20},

new Product(){ProductId=6,ProductName=”[无印严选]纯色V领长袖T恤”, Price=67M, Stock=50},

new Product(){ProductId=7,ProductName=”英伦学院派马夹”, Price=44M, Stock=40},

new Product(){ProductId=8,ProductName=”纯棉连帽宽松卫衣”, Price=66M, Stock=30},

new Product(){ProductId=9,ProductName=”纯棉多口袋工装裤”, Price=80M, Stock=990},

new Product(){ProductId=10,ProductName=”假两件长袖T恤”, Price=89M, Stock=30},

};

/// <summary>

/// 查询所有商品

/// </summary>

/// <returns>所有商品</returns>

public List<Product> GetProducts()

{

return productList;

}

/// <summary>

/// 根据商品Id查询商品

/// </summary>

/// <param name=”id”>商品编号</param>

/// <returns>商品</returns>

public Product GetProductById(long id)

{

return productList.FirstOrDefault(p => p.ProductId == id);

}

/// <summary>

/// 根据商品名称查询商品

/// </summary>

/// <param name=”id”>商品名称</param>

/// <returns>商品</returns>

public List<Product> GetProductByName(string name)

{

return productList.Where(p => p.ProductName == name).ToList();

}

4、 添加ASP.NET Web Service 到工程中,命名为ProductServic.asmx,如下图:

此Web Service调用ProductData类,完成数据查询操作,具体代码如下:

/// <summary>

/// Summary description for ProductService

/// </summary>

[WebService(Namespace = “http://tempuri.org/”)]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.ComponentModel.ToolboxItem(false)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

[System.Web.Script.Services.ScriptService]

public class ProductService : System.Web.Services.WebService

{

private ProductData dataSource

{

get

{

return new ProductData();

}

}

/// <summary>

/// Get the Products

/// </summary>

/// <returns></returns>

[WebMethod]

[ScriptMethod(ResponseFormat=ResponseFormat.Json,UseHttpGet=true)]

public List<Product> GetProducts()

{

return dataSource.GetProducts();

}

/// <summary>

/// 根据商品Id查询商品

/// </summary>

/// <param name=”object”>商品编号</param>

/// <returns>商品</returns>

[WebMethod]

[ScriptMethod(ResponseFormat=ResponseFormat.Json,UseHttpGet=true)]

public Product GetProductById(object id)

{

Product p = null;

if (id!=null)

{

int productId = 0;

int.TryParse(id.ToString(),out productId);

p = dataSource.GetProductById(productId);

}

return p;

}

/// <summary>

/// 根据商品名称查询商品

/// </summary>

/// <param name=”id”>商品名称</param>

/// <returns>商品</returns>

[WebMethod]

[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]

public List<Product> GetProductById(string name)

{

return dataSource.GetProductByName(name);

}

}    }

注:

Ø 引用命名空间:System.Web.Script.Services.ScriptService

Ø 给方法添加注解:[ScriptMethod(ResponseFormat = TheResponseFormat, UseHttpGet = true/false)]

ResponseFormat:方法要返回的类型,一般为Json或者XML

UseHttpGet:true表示“Get”可以访问此方法

5、 在Defualt.aspx页面引用JQuery类库

引用Google网络JQuery 类库http://ajax.googleapis.com/ajax/libs/jQuery/1.4.2/jQuery.js

或者本地类库<script src=”Scripts/jQuery-1.4.1.js” type=”text/JavaScript”></script>

6、 在Defualt.aspx页添加如下HTML代码:

<div id=”listContainer” class=”container”>

<div id=”title”>

Product List</div>

<table id=”productList”>

<thead>

</thead>

<tbody>

</tbody>

</table>

</div>

Jquery会动态向id=ProductList的Table中添加查询到的数据

7、 在Defualt.aspx页添加如下样式代码:

<style type=”text/css”>

body

{

font-family: Verdana,Arial;

}

.container

{

width: auto;

padding: 1.5em;

margin: 1em;

}

.container #title

{

font-size: 2em;

width: 100%;

border-bottom: groove 0.5em blue;

}

#productList

{

width: 100%;

border-collapse: collapse;

}

#productList td

{

padding: 1em;

border-style: solid;

border-width: 1px;

border-color: Blue;

margin: 0;

}

thead td

{

background-color: Yellow;

}

tbody tr:hover

{

background-color: #aaa;

}

</style>

8、 使用Jquery的Ajax方法调用Web Service中方法,代码如下:

$(document).ready(function () {

// Get Product list

$.ajax({

type: “GET”,

contentType: “application/json; charset=utf-8”,

url: “ProductService.asmx/GetProducts”,

dataType: “json”,

success: insertCallback,

error: errorCallback

});

function insertCallback(result) {

$(“#productList”).find(“tr:gt(0)”).remove();

if (result[“d”].length > 0) {

$(‘#productList > thead:last’).append(‘<tr><td>商品名称</td><td>价格</td><td>库存量</td></tr>’);

}

for (var i = 0; i < result[“d”].length; i++) {

var product = eval(result[“d”][i]);

$(‘#productList > tbody:last’).append(‘<tr onclick=”ShowDetail(‘ + product.ProductId + ‘)”><td>’ +

product.ProductName + ‘</td><td>’ +

product.Price + ‘</td><td>’ +

product.Stock + ‘</td></tr>’);

}

}

function errorCallback(XMLHttpRequest, textStatus, errorThrown) {

alert(errorThrown + ‘:’ + textStatus);

}

注:

$.ajax方法有以下属性:

Type:    HTTP请求方法,在做查询操作时,经常用Get方法

contentType:在请求头部的类型,由于Web Service返回Json对象,此处值为:application/json; charset=utf-8

url:求的URL地址

dataTyep:定义返回的类型

Success:调用成功时,要执行的方法

error:调用失败是,要执行的方法

9、 执行程序,效果如下:

至此,使用Jquery查询Web Service返回的JSon对象已经完成