.NET
免费开源开发平台
.NET是一种用于构建多种应用的免费开源开发平台,可以使用C#F#Visual Basic编写.NET应用。.NET用于生成多种类型的应用程序和库开发Web应用、Web API和微服务、云中的无服务器函数、云原生应用、移动应用、桌面应用、Windows WPF、Windows窗体、通用 Windows平台 (UWP)、游戏、物联网 (IoT)、机器学习控制台应用、Windows服务。.NET类库在不同应用和应用类型中共享功能,无论构建哪种类型的应用,代码和项目文件看起来都一样,可以访问每个应用的相同运行时、API和语言功能。
产生背景
.NET是开放源代码(托管于GitHub),使用 MIT 和 Apache 2 许可证。.NET 是 .NET Foundation 的项目。.NET就是微软用来实现XML,Web Services,SOA(面向服务的体系结构service-oriented architecture)和敏捷性的技术。对技术人员,想真正了解什么是.NET,必须先了解.NET技术出现的原因和它想解决的问题,必须先了解为什么他们需要XML,Web Services 和 SOA。技术人员一般将微软看成一个平台厂商。微软搭建技术平台,而技术人员在这个技术平台之上创建应用系统。从这个角度,.NET也可以如下来定义:.NET是微软的新一代技术平台,为敏捷商务构建互联互通的应用系统,这些系统是基于标准的,联通的,适应变化的,稳定的和高性能的。从技术的角度,一个.NET应用是一个运行于.NET Framework之上的应用程序。(更精确的说,一个.NET应用是一个使用.NET Framework类库来编写,并运行于公共语言运行时Common Language Runtime之上的应用程序。)如果一个应用程序跟.NET Framework无关,它就不能叫做.NET程序。比如,仅仅使用了XML并不就是.NET应用,仅仅使用SOAP SDK调用一个Web Service也不是.NET应用。
2014年4月的Build开发者大会上,微软宣布开源一批.NET库和相关技术,成立.NET基金会去管理和引导开源组件的开发。微软还将在Apache 2.0许可证下开源Roslyn编译器堆栈,Roslyn是微软所谓的编译器即服务,包含了C#和 Visual Basic.NET 编译器。.NET基金会由来自微软、GitHubXamarin的代表组成,Xamarin由GNOME创始人Miguel de Icaza等人创建,开发.NET开源实现。Xamarin向基金会贡献了它的部分库。de Icaza在接受采访时表示,微软已经变了,不仅仅移除了许可证中的限制,而且与Xamarin合作征求设计反馈,在创作共用许可证下发布文档。
2014年11月13日,为了进一步扩大云计算市场,微软将不再把.NET和Visual Studio等关键软件技术局限在Windows平台,今后还将兼容Linux、Mac OS X、iOS和Android。除此之外,微软还宣布将开放.NET核心服务器运行环境和框架的源代码,使得外部开发者也可以对这一软件开发平台做出贡献。
作为这一变化的一部分,微软将允许开发者使用.NET运行环境和框架,来为Linux和Mac开发基于服务器和云端的应用。微软还推出了功能齐全的新版Visual Studio 2013,并将免费对独立开发者、学生、小企业等用户开放。
运行环境
.NET 5 和.NET CORE均支持 Windows, Linux, 和macOS系统。
如图《版本历史及Windows 所安装的版本》所示,汇总了版本历史记录以及标识 Windows 所安装的版本。
每个新版本的 .NET Framework 都会保留早期版本中的功能并会添加新功能。 CLR 由其自己的版本号确定的。 某些版本的 .NET Framework 包含新版本的 CLR,而其他版本的 .NET Framework 使用早期版本的 CLR。 例如,.NET Framework 4 包含 CLR 4,而 .NET Framework 3.5 包含 CLR 2.0。 (没有版本 3 的 CLR。)虽然 .NET Framework 4.5 是 .NET Framework 4 的就地更新,基础 CLR 版本号成为 CLR 4.5。
通常,您不应卸载计算机上安装 .NET Framework 的任何版本,因为您使用的应用程序可能取决于特定版本,并且可能中断,如果移除该版本。 您可以同时在一台计算机上加载 .NET Framework 的多个版本。 这意味着可以安装 .NET Framework,而无需卸载旧版本。
应用组件
客户端应用
组成.net软件技术的组件,组件之一,“智能”客户端应用软件操作系统,包括PC、PA、手机或其他移动设备通过互联网、借助Web Services技术,用户能够在任何时间、任何地点都可以得到需要的信息和服务。例如:可以在手机上阅读新闻、定购机票、浏览在线相册等等。CRM系统,应用了.NET的解决方案后所有的业务人员便可以通过手机或PDA直接访问客户信息了。
WebServices
Web Services是智能终端软件的基础,微软为用户创建智能终端提供了一整套丰富的解决方案,包括:
.NET Framework- 智能终端实现跨平台(设备无关性)的
Visual Studio .NET – 建立并集成Web Services和应用程序的快速开发工具
Microsoft Windows Server 2003 – 新一代的企业服务器,用于提供建立和发布各种解决方案
Microsoft Office Professional Edition 2003 – 内建的工具集也能帮助开发智能终端
Web Services是.NET的核心技术。正如Web是新一代的用户与应用交互的途径,XML是新一代的程序之间通讯的途径一样,Web Services是新一代的计算机与计算机之间一种通用的数据传输格式,可让不同运算系统更容易进行数据交换。Web Services有以下几点特性:Web services允许应用之间共享数据;Web services分散了代码单元;基于XML这种internet数据交换的通用语言,实现了跨平台、跨操作系统、跨语言。那微软的ASP和Web services究竟有什么不同呢,ASP仍然是一个集中式计算模型的产物,只不过是披着一层互联网的外衣。但Web Services却是一个迥然不同的精灵,它秉承“软件就是服务”的真言,同时顺应分布式计算模式的潮流。而它的存在形式又与以往软件不同。这种组件模式,小巧、单一,对于开发人员来讲,开发成本较低。
在这里指出Web services不是微软发明的,同样也不属于微软专有。Web services是一个开放的标准,和HTTP、 XML、SOAP一样。他们是一个工业标准而非微软标准,WS-I是为了促进Web Services互通性的联盟组织,最初是由IBM和微软所发起,其它的成员包括BEA System、惠普计算机(HP)、甲骨文(Oracle)、英特尔(Intel)和SUN 计算机(Sun Microsystem)。如今网络上存在的大多Web services其实没有使用.NET构架,Web services具有互操作属性,你同样可以使用Windows开发客户端来调用运行于Linux上面的Web services的方法。
接口规范
先前提到的接口规范问题,在.NET中,Web service接口通常使用Web Services Description Language (WSDL)描述。WSDL 使用XML来定义这种接口操作标准及输入输出参数,看起来很像COM和CORBA的接口定义语言(IDLS)Interface Definition Languages。接口定义后就必须使用一些协议调用接口,如SOAP协议,SOAP源于一种叫做XML RPC(XML远程进程调用remote procedure calling)的协议,而Java则根据XML-RPC发展了自己的JAX-RPC协议用来调用Web Services。发布和访问Web Services的接口就用到UDDI了,这里我们只需要知道WSDL使用XML定义Web Services接口,通过SOAP访问Web Services,在internet上寻找Web Services使用UDDI就行了。服务器架构——Microsoft Windows Server System Microsoft提供了最佳的服务器构架—Microsoft Windows Server System—便于发布、配置、管理、编排Web Services。为了满足分布式计算的需要微软构造了一系列的服务器系统,这些内建安全技术的系统全部支持XML,这样加速了系统、应用程序以及同样使用Web Services的伙伴应用之间的集成。
Microsoft Windows Server System包括:
Microsoft Application Center 2000 - 配置和管理Web应用程序
Microsoft BizTalk Server 2002 - 建立基于XML的跨应用和组织的商业逻辑
Microsoft Commerce Server 2002 – 能够迅速建立大规模电子商务的解决方案
Microsoft Content Management Server 2002 – 管理动态电子商务网站的目录
Microsoft Exchange Server 2000 – 用于进行随时随地的通讯协作
Microsoft Host Integration Server 2000 – 用于和主机系统之间传输数据
Microsoft Internet Security and Acceleration Server 2000 (ISA Server) – internet连接
Microsoft Mobile Information Server 2002 – 用于支持手持设备
Microsoft Operations Manager 2000 – 描述企业级解决方案的操作管理
Microsoft Project Server 2002 - 提供项目管理的最佳方案
Microsoft SharePoint Portal Server 2001 – 查询、共享、发布商业信息
Microsoft SQL Server 2000 – 企业级数据库
Microsoft Visual Studio .NET和Microsoft .NET Framework对于建立,发布并运行Web Services解决方案。
微软官方的教程。
CLR 与 CIL
.NET的初级组成是CIL和CLR。CIL是一套运作环境说明,包括一般系统、基础类库和与机器无关的中间代码,全称为通用中间语言(CIL)。CLR则是确认操作密码符合CIL的平台。在CIL执行前,CLR必须将指令及时编译转换成原始机械码。
所有CIL(通用中间语言)都可经由.NET自我表述。CLR检查元资料以确保正确的方法被调用。元资料通常是由语言编译器生成的,但开发人员也可以通过使用客户属性创建他们自己的元资料。
如果一种语言实现生成了CIL,它也可以通过使用CLR被调用,这样它就可以与任何其他.NET语言生成的资料相交互。CLR也被设计为作业系统无关性。
当一个汇编体被载入时,CLR执行各种各样的测试。其中的两个测试是确认与核查。在确认的时候,CLR检查汇编体是否包含有效的元资料和CIL,并且检查内部表的正确性。核查则不那么精确。核查机制检查代码是否会执行一些“不安全”的操作。核查所使用的演算法非常保守,导致有时一些“安全”的代码也通不过核查。不安全的代码只有在汇编体拥有“跳过核查”许可的情况下才会被执行,通常这意味着代码是安装在本机上的。
通过.NET,你可以用SOAP和不同的Web services进行交互。
3.0版本
.NET Framework 3.0(曾用名WinFX)是微软为操作系统Windows Vista(旧称“Longhorn”)而特别设计的API。.NET Framework是对.NET架构和Win32 API的扩展。虽然Win32 API仍然存在于Windows Vista中,但是在WinFX中不能通过它直接调用。另外,WinFX将提供给.NET程序员更加简便地方式来调用Windows中的功能
.NET Framework 3.0同样能在Windows XPWindows Server 2003的计算机上运行,这样增加了能够运行.NET Framework 3.0程序的计算机数量。由于向后兼容,能够更加容易将这些技术介绍给开发人员和最终用户。2006年9月1日,微软发布了.NET Framework 3.0的RC版本,开发人员能够无需安装Vista就可以体验这些新的技术。
.NET Framework 3.0并没有新版本的CLR,而是在.NET Framework 2.0的基础上增加了几个新的部件,所以并没有任何程序设计语言有新的语法特性,如果要安装.NET Framework 3.0,则必须先安装.NET Framework 2.0,.NET Framework 3.0可以完全向下兼容.NET Framework 2.0。
.NET Framework 3.0主要由的四部分组成:
动态编程
C#是静态强类型语言。而在很多情况下,提供“动态”行为,是常常发生的事情,例如通过反射在运行时访问.NET类型、调用动态语言对象、访问COM对象等,都无法以静态类型来获取。因此, C# 4.0引入的又一个全新的关键字dynamic,也同时引入了改善静态类型与动态对象的交互能力,这就是动态查找(Dynamic Lookup)例如:
就像一个object可以代表任何类型,dynamic使得类型决断在运行时进行,方法调用、属性访问、委托调用都可动态分派。同时,动态特性还体现在构建一个动态对象,在C# 4.0实现IDynamicObject接口的类型,可以完全定义动态操作的意义,通过将C#编译器作为运行时组件来完成由静态编译器延迟的操作,例如:
在具体执行过程中,C#的运行时绑定器基于运行时信息,通过反射获取d的实际类型Foo,然后在Foo类型上就MyMethod方法进行方法查找和重载解析,并执行调用,这正是动态调用的背后秘密:DLR。在.NET 4.0中将引入重要的底层组件DLR(Dynamic Language Runtime,动态语言运行时),除了实现动态查找的基础支持,DLR也同时作为基础设施为类似于IronRuby、IronPython这样的动态语言提供统一的互操作机制。总而言之,动态编程将为C#在以下领域产生巨大的变革:
· Office编程与其他COM交互。
·动态语言支持,在C#中消费IronRuby动态语言类型将并非难事,体验动态语言特性指日可待。
· 增强反射支持。
以调用IronPython为例,我们只需引入IronPython.dll,IronPython.Modules.dll,and Microsoft.Scripting.dll,即可通过创建ScriptRuntime在C#中HostingIronPython环境,进而来操作动态语言的类型信息。
ScriptRuntime py = Python.CreateRuntime();
虽然从微软当前提供的技术资料和CTP演示中,动态查找还存在或多或少的问题,但是在“动态”大行其道的今天,我们无法回避也必须拥抱这个未来的主角,因为我坚信明天会更好。
并行计算
并行计算的出现,是计算机科学发展的必然结果,随着计算机硬件的迅猛发展,在多核处理器上工作已经是既存事实,而传统的编程模式必须兼容新的硬件环境才能使计算机性能达到合理的应用效果。用Anders大师的话说:未来5到10年,并行计算将成为主流编程语言不可忽视的方向,而4.0为C#打响了实现并发的第一枪。
未来的.NET Framework 4.0中将集成TPL(Task Parallel Library)和PLINQ(Parallel LINQ),这也意味着未来我们可以应用C# 4.0实现并行化应用,在统一的工作调度程序下进行硬件的并行协调,这将大大提高应用程序的性能同时降低现存并发模型的复杂性。
那么,我们应该一睹为快应用C#武器来开发并发环境下的超酷感受,在System.Threading.Parallel 静态类提供了三个重要的方法For、Foreach、Invoke可以为我们小试牛刀:
在线程争用执行情况下,相同的操作在双核平台下运行,以StopWatch进行精确时间测试,并行环境下的执行时间为 2001ms,而非并行环境下的执行时间为4500ms,并行运算的魅力果然名不虚传。我们再接再厉应用PLINQ执行对于并行运算的查询、排序等,当前PLINQ支持两种方式ParallelEnumerable类和ParallelQuery类,例如:
更详细的对比示例留待读者在实践中对此进行讨论,并行计算为托管代码在多核环境下的性能优化提供了统一的解决方案,而未来我们会做的更好。
备注:实际上,我们可以选择下载安装Microsoft Parallel Extensions to the .NET Framework 3.5June 2008 CTP包,就可以在.NET 3.5环境下体验并行计算的无穷魅力。
协变和逆变
协变和逆变,是为解决问题而生的。而要理清解决什么样的问题,需要首先从理清几个简单的概念开始。首先我们进行一点操作:
Derived d = new Derived();
Base b = d;
Derived类型继承自Based类型,由Derived引用可以安全的转换为Based引用,而这种转换能力可以无缝的实现在Derived数组和Base数组,例如:
Derived[] ds = new Derived[5];
Base[] bs = ds;
而这种原始转换(由子类转换为父类)方向相同的可变性,被称为协变(covariant);其反向操作则被称为逆变(contravariant)。当同样的情形应用于泛型时,例如:
List ds = new List();
List bs = ds;
类似的操作却是行不通的。所以,这就成为C# 4.0中完善的问题——泛型的协变与逆变:
List bs = new List(); List ds = new List();
bs = ds; //List;支持对T协变
ds = bs; //List;支持对T逆变
而在C# 4.0中,伴随着协变与逆变特性的加入,C#引入两个in和out关键字来解决问题。
public interface ICovariant {
T MyAction();
}
public interface IContravariant
{
void MyAction(T arg);
}
其中,out表示仅能作为返回值的类型参数,而in表示仅能作为参数的类型参数,不过一个接口可以既有out又有in,因此既可以支持协变、支持逆变,也可以同时支持,例如:
public interface IBoth
{
}
默认参数
命名参数和可选参数是两个比较简单的特性,对于熟悉其他编程语言的开发者来说可选参数并不陌生,为参数提供默认值时就是可选参数:
public void MyMethod(int x,int y = 10,int z = 100) {
}
因此,我们可以通过调用MyMethod(1)、MyMethod(1,2)方式来调用MyMethod方法。而命名参数解决的是传递实参时,避免因为省去默认参数造成的重载问题,例如省去第二个参数y调用时,即可通过声明参数名称的方式来传递:
MyMethod(20,z: 200);
相当于调用MyMethod(20,10,200),非常类似于Attribute的调用方式。虽然只是小技巧,但也同时改善了方法重载的灵活性和适配性,体现了C#语言日趋完美的发展轨迹。
当然,除此之外.NET 4.0还增加了很多值得期待的平台特性,也将为C#编码带来前所未有的新体验。
以上相关版权归作者。
.NET控件
.NET标准控件根据其应用环境分为两类:
Windows Form控件:主要用于Windows应用程序的开发。所有的Windows控件都是从Control类中派生来的,该类包含了所有用户界面的Windows Form组件,其中也包括Form类。Control类中包括了很多位所有控件所共享的属性、事件和方法。它包含复选框、文本框、按钮、标签、图像列表等。
Web窗体控件:主要用于Web应用程序的开发。它是专门针对Asp.NETWeb窗体设计的服务器控件。Web窗体控件包含在命名空间System.Web.UI.WebControls中,当用户使用Visual Studio创建Web窗体页面时,会自动在后台代码文件中添加引用该命名空间的Using语句。
.NET Compact Framework 提供了可以满足大多数设备项目需要的Windows Form控件。若要使用这些控件没有的功能,可以从公共控件派生您自己的自定义控件。可以通过定义从 Control 类或从程序集中的现有 UserControl 继承的公共类型创建自定义控件。
最简单的控件自定义是重写公共控件的方法。例如,可以重写 TextBox 控件的 OnKeyPress 继承方法,提供将输入限制为数字字符的代码。
如若觉得自定义控件过于浪费时间和复杂,也可以从受信任的来源下载控件,并通过添加引用来导入自定义控件。支持这些自定义的.NET的控件有:ComponentOne Studio,Spread,ActiveReportsMultiRow等。
加密处理
信息安全是计算机应用的首要问题之一,但关于.NET加密功能的范例却少之又少。有鉴于此,本文探讨了在.NET平台下加密/解密文件的一般过程,并提供了一个加密/解密文件的工具。
Web服务以不容置疑的态势迅速发展,促使许多单位开始考虑.NET之类的开发平台。但是,出于对安全问题的担心,一些单位总是对采用新技术心存顾虑。好在有许多成熟的安全和网络技术,例如虚拟私有网络(VPN)和防火墙等,能够极大地提高Web服务应用的安全和性能,让开发者拥有选择安全技术的自由,而不是非得使用尚在发展之中的XML安全技术不可。
虽然安全是信息系统的首要问题,但有关.NET安全和加密工具的范例却少之又少。看看大多数.NET书籍的目录,找不到任何有关安全的题目,更不用说关于密码系统的探讨了。
有鉴于此,本文将介绍如何在VB开发中运用.NET的加密和密钥生成类,提供一个可用来加密和解密文件的工具Cryption。有了这个工具,你就可以在硬盘上保存各种机密文件,例如所有的密码/用户名字信息、收支文件、以及其他想要保密的信息,还可以加密那些通过Internet发送的文件。加密技术的用途非常广泛,你可以进一步定制本文提供的工具满足某些特殊需要,例如增加批处理能力等。
安全威胁
攻击和泄密是计算机面临的两大安全威胁。攻击可能来自病毒,例如它会删除文件、降低机器运行速度或引发其它安全问题。相比之下,泄密往往要隐蔽得多,它侵害的是你的隐私:未经授权访问硬盘文件,截取通过Internet发送的邮件,等等。泄密还可能伴随着攻击,例如修改机密文件等。
针对泄密的最佳防范措施就是加密。有效的加密不仅杜绝了泄密,而且还防范了由泄密引发的攻击。加密技术有时还用于通信过程中的身份验证——如果某个用户知道密码,那么他应该就是那个拥有这一身份的人。
然而必须说明的是,没有一种防范泄密的安全技术是绝对坚固的,因为密码有可能被未经授权的人获得。
加密前提
首先,要想使用.NET的安全功能,就必须用Imports语句引入加密用的包。试验本文涉及的任何代码之前,请在VB代码窗口的顶部加入下列Imports语句:
Imports System
Imports System.Text
Imports System.Security.Cryptography
第二,美国政府过去限制某些加密技术出口。虽然这些限制不再有效,.NET框架在Windows的出口版本中禁用了“高级”加密技术。如果你的 Windows不带高级加密能力,可以从微软网站下载更新包:对于Windows 2000,安装Service Pack 2包含的High Encryption Pack;对于NT,安装Service Pack 6a。对于Windows ME、95、98的用户,IE 5.5也包含了High Encryption Pack。
工具概况
本文提供的工具可用来加密和解密文件,如果你急着给一些文件加密,只需直接启动本文后面提供的工具即可。
这个工具提供了一个用来输入文件名字的文本框和一个输入密钥的文本框,通过便捷的用户界面提供加密、解密和密钥生成功能。上方的文本框用来输入待加密/解密文件的名字;下面的文本框用来输入8个字符的密码。执行加密操作之后将生成一个新的文件,这个经过加密的文件和原始文件在同一目录下,文件名字也和原始文件的一样,但加上了“xx”后缀,例如,假设原始文件是MyFile.txt,则加密得到的文件是MyFilexx.txt。
加密好之后,原始文件不一定非删除不可,但一般来说最好删除,因为加密的根本目的就是为了隐藏原始文件的数据。如果要从加密后的文件恢复出原始文件,在上面的文本框中输入MyFilexx.txt,然后提供密码,Cryption工具将创建一个与原始文件一样的MyFile.txt文件。也就是说, Cryption把文件名字后面的“xx”看作是要求解密密文的标志。
注意:加密文件之后如果忘记了用来加密该文件的密码,再想恢复出原始文件就不可能了。当然,这与密码本身的复杂程度有关,要想保证文件的安全,最好采用较复杂的密码,例如混合运用字母、数字和特殊字符(如“$”符号等)。
.NET提供的加密技术不止一种,不过本文讨论的主要是对称加密对称加密也称为私有密钥加密,它的特点是加密和解密用的是同一个密钥(实际上是同一种算法),解密方和加密方都有责任保障密码的安全(对于公用密钥、不对称加密,密钥一共有两个,其中一个密钥是公开的,这是当前公认最有效的加密技术,但就速度而言要比对称加密算法慢不少)。
在正式利用.NET加密类加密文件之前,首先必须从用户提供的密码生成一个密钥。密钥可以利用Hash函数生成,Hash函数把用户的密码字符串转换成一组类似随机数序列的、无意义的数据,这组数据可作为密钥使用,在加密过程中对原始数据进行唯一性变形处理。
例如,用密钥加密数据的一种办法是把原始数据的ASCII码加上密钥的ASCII码:
密钥:ab = ASCII: 97,98
数据:merry = ASCII: 109,101,114,114,121
把这组数据的ASCII码加上密钥的ASCII码(必要时重复使用密钥),得到的加密结果是:
97 98 97 98 97
+109 +101 +114 +114 +121
206 199 211 212218
对于同样的数据,Hash算法总是生成同样的结果(这就是说,对于同一个密码,同一Hash算法总是生成相同的bit序列)。实际上,在本文提供的代码中,利用.NET的SHA1CryptoServiceProvider类的ComputeHash方法可以验证这一点,例如,对于同一个输入参数 morph,任何时候该方法总是返回下面的结果:124,230,93,253,197,206,136,72。因此,如果有人知道密码以及生成密钥的算法,他也可以轻松地推算出密钥。
加密/解密
.NET加密技术要求密钥有确定的长度,例如,DES(Data Encryption Standard)函数要求密钥的长度是64位,Rijndael则要求128、192或256位长度的密钥。密钥越长,加密强度越高。对于DES之外的加密算法,查询LegalKeySizes属性即可得到它允许的密钥长度,包括MinSize(支持的最小密钥长度)、MaxSize(最大密钥长度)、 SkipSize(增量)。SkipSize表示密钥最大长度和最小长度之间可用长度的间隔,例如,Rijndael算法的SkipSize值是64位。
利用下面的代码可以得到密钥的长度信息:
' 创建DES加密对象
Dim des As New DESCryptoServiceProvider()
Dim fd() As KeySizes
fd = des.LegalKeySizes() 'tells us the size(s),in bits
运行上面的代码,得到的结果是64、64、0。如果把加密对象的声明改成TripleDESCryptoServiceProvider(),得到的结果是128、192、64。
说明:DES算法要求输入一个8字节的密码,但实际使用的密钥只有56位(7个字节),每一个字节的最后一位不用(它作为校验位使用,但不用于实际的加密过程)。
下面的代码开始生成本文示例程序的密钥:
Public Class Form1
Inherits System.Windows.Forms.Form
' 保存密钥的8字节的数组
Private TheKey(7) As Byte
' 在向量中放入一些随机数据
Private Vector() As Byte = {&H12,&H44,&H16,&HEE,&H88,&H15,&HDD,&H41}
首先,代码定义了保存密钥和初始向量(请参见稍后的详细说明)的两个变量。向量的初值这里用随机数据填充,当然,通过密码和Hash算法也可以获得向量的初值。下面的过程从用户输入的密码创建出密钥:
Sub CreateKey(ByVal strKey As String)
' 保存密钥的字节数组
Dim arrByte(7) As Byte
Dim AscEncod As New ASCIIEncoding()
Dim i As Integer = 0
AscEncod.GetBytes(strKey,i,strKey.Length,arrByte,i)
' 获得密码的Hash值
Dim hashSha As New SHA1CryptoServiceProvider()
Dim arrHash() As Byte = hashSha.ComputeHash(arrByte)
' 将Hash值保存到密钥
For i = 0 To 7
TheKey(i) = arrHash(i)
Next i
End Sub
用户的密码(strKey)传入到CreateKey过程,分解成一组ASCII值保存到一个字节数组。把这个字节数组传递给 SHA1CryptoServiceProvider类的ComputeHash方法,返回一个Hash值。把这个Hash值保存到TheKey数组,供以后的加密/解密过程使用(注意SHA1CryptoServiceProvider实际能够支持160位,但本文示例程序只用到64位)。
那么,初始向量究竟起什么作用呢?这个字节数组有8个元素,就象密钥一样,但向量和密钥的作用是不同的,向量用来避免DES之类的算法一个特有的问题。在DES之类的算法中,原始数据被分成8字节一块然后分别处理。DES在加密一块数据时,要用到前一块数据的模式,也就是说,如果改动了原始数据中第一块的某个字符,所有后继的块的内容都将随之改变,从而避免了一系列相连接的块中出现重复块的问题。
例如,假设你一时高兴,发了一个邮件,内容只有几个重复的单词“Melanie! Melanie! Melanie! Melanie!”,在密钥和块序列中前一块的共同作用下,加密之后的密文不会出现重复现象。然而,进一步考虑这个加密过程可以发现,如果用同一个密钥加密多个邮件,且邮件开头的问候语都相同,则邮件开头的一部分很容易受到攻击。由于这个原因,我们用初始向量来模拟前一个块。
本文加密/解密工具中的下面这段代码示范了如何加密文件:
Sub Encrypt(ByVal inName As String,ByVal outName As String )
Try
' 创建缓冲区
Dim storage(4096) As Byte
' 已经写入的字节数量
Dim totalBytesWritten As Long = 8
' 每次写入的字节数量
Dim packageSize As Integer
' 声明文件流
Dim fin As New FileStream(inName,FileMode.Open,FileAccess.Read)
Dim fout As New FileStream(outName,FileMode.OpenOrCreate,FileAccess.Write)
fout.SetLength(0)
'源文件的大小
Dim totalFileLength As Long = fin.Length
' 创建加密对象
Dim des As New DESCryptoServiceProvider()
Dim crStream As New CryptoStream(fout,_
des.CreateEncryptor(TheKey,Vector),_
CryptoStreamMode.Write)
' 输出加密后的文件
While totalBytesWritten < totalFileLength
packageSize = fin.Read(storage,0,4096)
crStream.Write(storage,0,packageSize)
totalBytesWritten = Convert.ToInt32(totalBytesWritten + _
packageSize / des.BlockSize * des.BlockSize)
End While
crStream.Close()
Catch e As Exception
MsgBox(e.Message)
End Try
End Sub
注意这段代码创建了三个文件流:fin,表示明文形式的原始文件;fout,加密结果文件;crStream,加密流,用来把DES加密的结果转入输出文件fout。增加一个crStream流的好处是不必把结果保存到临时文件或缓冲区。
加密过程与解密过程的唯一重要区别是,执行解密时,我们将使用DESCryptoServiceProvider对象的另一个方法CreateDecryptor,除此之外,两者其余的处理步骤(包括参数,文件流,等等)基本相同。
防止破解
黑客和密码专家破解加密文件的办法主要有两个,第一是搜索密文是否有重复现象,第二是用暴力破解法获得密钥。首先我们考虑一下初始向量如何防止重复现象,然后再探讨一下防止暴力破解的关键问题。
破解密文的第一种方式是搜索样本——特别是重复的样本。人们在写信的时候总是喜欢用同样的文字开头,例如“亲爱的XXX”、“Dear Sir”等,如果多个邮件的开头文字相同且通过同一密钥加密,则每个密文信件的开头也相同。假设Antonio写给Melanie的所有加密信件都有相同的问候语“@4^F (2$@Fx”,解密者就会首先检查开头的几个单词是不是“Dear Melanie”。解密机密文件的一个重要步骤就是猜测文件中应当会出现的几个单词,所以我们不应该给解密者提供这种方便。在本文的示例中,初始向量的内容被附加到文件的开头,从而防止了出现重复现象。只有信件的开头才容易受到此类攻击。
计算机的运算速度和精度要远远超过人,特别擅长处理一些重复的任务,例如尝试每一种可能的密钥组合最终破解密钥。DES加密算法本身是不安全的,这种加密算法早在70年代就已经公之于众。而且,破解者如果想要让搜索密钥的过程自动化,同样可以方便地运用.NET的DESCryptoServiceProvider类。
对于一个128位、结合运用密钥/初始向量的加密方案,计算机尝试每一种可能的密钥组合要花多少时间?专家们的看法并不一致,有人认为需要数月,也有人认为装有专用硬件的价值6位数的计算机每秒能够验证数十亿个密钥,破解DES密文只需数小时。如果你的机密值得花数月时间去破解,那么最好改用 TripleDES或其他加密算法。从TripleDES的名字也可以猜出,这种加密方式采用三重数据加密标准算法,所以密钥的长度是192位,而不是 64位的DES密钥。记住,在其他条件相同的情况下,密钥越长,安全程度越高。
结束语:现在你已经了解了. NET DES加密算法的使用过程,接下去可以研究.NET的其他安全功能,包括极具吸引力的公用密钥加密方案。虽然公用密钥加密方案执行起来速度慢一些,但加密效果一般要比TripleDES好。
最新修订时间:2024-09-14 16:44
目录
概述
产生背景
参考资料