注意:本页面内容为W3xue原创,未经授权禁止转载,违者必究!
来源:W3xue 发布时间:2018/3/15 13:36:14
信息传输过程中,总是容易发生安全问题的地方,传统的通讯方式是如此,例如古代战争中的信使可能被截杀,信鸽可能被捕获,现代信息技术中的通讯也是如此。在一个典型的C/S架构中,服务器与浏览器之间的通讯容易受到很多的攻击,包括:
- 网络监视。攻击者利用软件或设备截获通讯数据包,如果数据包没有加密,攻击者就可以看到全部的传输信息。当然,此类软件或设备也可以用来作为安全诊断工具,但在很多时候,它们是被攻击者使用的。
- 数据篡改。攻击者修改传输中的数据包,并篡改数据,使接收方接受不到正确信息。
- 密码破解。攻击者使用被盗用的密码或密钥,或直接破解密码。
- 地址欺骗。攻击者使用特殊的程序构造IP包,使得这个包看起来像是来自受信任的传输者的IP地址。
- “中间人”攻击。攻击者在不了解受影响方的情况下,监视、获取并控制两台正在通宵的计算机之间的传输数据,例如,攻击者而会为数据传输重新制定路由。
为了保护通信的信息安全,维持信息的完整性,我们需要对传输的信息进行加密,防止攻击者的截获和篡改。
一、密码系统
1、密码系统概述
密码学是一门古老的学问。从古代的密文军报、虎符(一种兵符)到日常生活中的锁和钥匙,无一不是密码学的应用。而现代通讯过程中,需要对信息进行加密和解密,这就涉及到密码系统的相关知识。
古代时,最经典的两个加密技巧是:一、置换(Transposition cipher):将字母顺序重新排列,例如‘help us’变成‘ehpl su’。二、替代(substitution cipher):有系统地将一组字母换成其他字母或符号,例如‘go to secret road’变成‘hp up tfdsfu spbe’(每个字母用下一个字母取代)。
在现代计算机体系中,简单的加密方法显然已经不能满足日益增长的安全需求。我们需要更加复杂、健壮的密码系统。这个密码系统必须做到以下几点:一、保护用户身份和数据不被读取;二、保护数据不被篡改;三、确认数据来源于确定的用户,而不是不受信任的第三方。
众所周知,密码系统有对称和不对称(又称非对称)两种方式。这取决于加密和解密的方式。
加密的过程就是将数据变的不规则的数据的过程,加密使得攻击者想要解密密文变的更加困难且耗时。在实际环境中,email、电子商务数据、文件存储、数据库链接、客户端与服务器端连接常常会用到加密过程。
加密数据通常需要使用加密算法(密码)和机密数据(密钥),密钥可以防止信息被解码(即使加密算法是公开的)。但是,如果一旦密钥被泄露,即使是功能最强大的算法也会变的无济于事。所以,密钥系统是整个密码系统的关键,密钥的生成、存储、交换都必须受到严格的保护。切忌在密钥交换过程中使用明文进行传输。
2、对称加密算法
对称加密算法使用数据发送方和接收方都认同的单一私钥(又被称作“会话密钥”),此密钥即被用来加密数据,也用来解密数据。
对称加密算法的优点在于,快速、有效,适合对大流量数据进行加密。其缺点也显而易见,密钥在交换时很难受到严格的保护,需要经常更换回话密钥,为每条加密信息创建不同的回话密钥。
3、不对称加密算法
不对称加密算法使用2种密码:即公钥和私钥,私钥必须对未经授权的用户保密,公钥则可以向所有人公开。需要注意的是:
- 每个用户都持有私钥和公钥。
- 用公钥加密的信息只能用私钥解密。
- 用私钥加密信息时,任何公钥持有者都能确认,此消息由私钥所有者发出。
- 由于算法较为复杂,不对称加密的安全性要高于对称加密,但其效率不如对称加密。
公钥和私钥很显然存在某种规律,或者说联系。一般情况下,它们是存在数学关联性的,这种数学关联性必须足够复杂,这样,只要密钥的长度足够长,以现有的计算机计算速度,想要短时间内破解是不可能的。例如,以一个足够长的半质数(两个质数的乘积)作为公钥,以其中一个质数因子作为私钥,就算攻击者知道了公钥,但想要破解这是哪两个质数的乘积需要做海量的运算。当然,如果真正意义上的量子计算机被制造出来,现有的基于电子计算机的密码系统将被秒杀,就算算法不变,其强度要以指数级上升。
4、交换和存储密钥
由于对称加密的安全性问题,和不对称加密的效率问题,在实际使用中,2种加密方式通常混用。
一个常用的混用方式是,利用不对称加密的安全性,传输一个会话密钥,利用这个会话密钥再对剩下的信息进行对称加密解密。而会话密钥也常常变更。
密码系统中,最难的部分就是对私钥进行保护,因为公钥是公开的,私钥成了整个系统的关键点和薄弱环节。可以把密钥存储在一个被访问控制列表(即ACL,之前的文件系统安全章节有介绍)保护的位置(例如文件系统或注册表),这个ACL一般被设置成只给应用程序读取该资源,而完全控制权只属于创建者和系统管理员。这样,就可以利用操作系统的安全性增强私钥的安全性。
Windows 2000以上操作系统还可以使用DPAPI(数据保护API)存储密钥。DPAPI能够消除使用密码的应用程序所带来的密钥管理问题。DPAPI 使用与 DPAPI 函数(CryptProtectData和CryptUnprotectData)的调用代码关联的用户帐户的密码,以便派生加密密钥。因此,是操作系统而非应用程序管理着密钥。不需要显式的密钥管理,可以利用系统提供的函数生成用户特定或计算机特定的加密数据。只有其登录凭据和最初加密数据的用户凭据相匹配才能解密该数据,而且通常只能在加密该数据的计算机上进行解密。如果使用SYSTEM账户(如ASP页)运行进程,则可以使用特定的函数将密钥存储到本地安全机构(LSA),不过LSA只能存储少量的密钥。而且,诸如LSADump2.exe这样的管理员用工具仍然能够看到存储的密钥。
密钥存储是设计安全系统时最难的部分,通常的原则是:尽可能避免存储密钥。
如果一味的追求性能,使用一些追求方便与速度的办法,例如将密码存储到程序的源代码中,就算程序经过编译,人们无法读取源代码,但破解这样的密码还是很容易的。
如果密钥是类似一串简单的字符串,使用某些工具来转储dll或exe中的字符串,使用这种方法就可以确定密码,攻击者通过不停的尝试和程序显示的错误信息,来确定哪个是密钥字符。由于代码是遵循一定的规律编写的,静态的数据也是固定的,但密钥是随机的,如果把随机的密钥存储在源代码中,可以通过某些寻找信息熵密度的工具,来一步步确定密钥的存储位置。因此,总的来说,把密钥存储到源代码中或者程序的配置文件中,都是极其不安全的。
按有效时间来说,密钥分为两类:短期密钥和长期密钥。短期密钥又被成为临时密钥,并被诸如IPSec、SSL/TLS、RPC(Remote Procedure Call,远程过程调用)和DCOM(分布式组件对象模型)等很多网络协议所采用。密钥的生成和管理过程,应用程序和用户是不可见的。长期密钥一般用于身份验证、完整性检查和认可,或者是建立临时密钥。例如,使用SSL/TLS时,服务器使用被其公钥证书标识的私钥,为每个加密的SSL/TLS会话生成临时密钥。长期密钥也可以用来保护数据库和文件中的永久数据,因为这些数据会长期保存,所以攻击者在很长一段时间内会尝试破解密钥。因此,长期密钥最好采取强度更大、更私有化的方式生成和保护。
5、密钥管理方法
密钥是整个密码系统的核心,对密钥的管理也是重中之重,下面列出一些较好的密钥管理办法:
一是使用适当的密钥长度。密钥越短,越容易被破解。对不同的算法生成的密钥有不同的破解方式。例如,破解大多数的对称密码(例如DES和RC4,本站工具里有在线加密解密工具),攻击者需要尝试每个密钥;破解RSA密钥,攻击者需要获取用来创建公钥和私钥的随机数值,这个过程叫做因子分解。所以,不能说112位3DES(TripleDes)密钥的安全性就低于512位的RSA密钥,因为生产它们的方式不同,破解它们的方式也随之不同。实际上,对512位的RSA密钥破解,要快于对112位3DES密钥的暴力破解。
如果用不对称密钥保护对称密钥,应该使用适当长度的不对称密钥。如果用来保护对称密钥的不对称密钥长度不够,那么,暴力破解这个不对称密钥要来的更加容易。下表表述了它们应有的长度关系:
对称密钥长度 | 对应RSA模长(位) | 对应DSA子群长(位) |
---|---|---|
70 | 947 | 128 |
80 | 1228 | 145 |
90 | 1553 | 153 |
100 | 1926 | 184 |
150 | 4575 | 279 |
200 | 8719 | 373 |
250 | 14596 | 475 |
从上表可以看出,要用RSA保护80位的对称密钥,RSA密钥长度至少需要1228位。
二是使密钥接近数据源。这样做的原因是,“移动性”很高的机密只能在较短的时间内保密,所有的代码都有缺陷,访问机密信息的次数越多,留给攻击者的机会就越多。安安静静的把密钥存储在某地,永远都比读取或移动它来的安全。
一个糟糕的编程方式是,通过某一串函数,读取永久存储区的密钥,然后通过一系列处理函数,对密钥进行处理,最后通过加工的数据执行某些程序。这样做的缺点是,每个函数和执行过程都有可能成为攻击者攻破系统的薄弱环节。
我们应该采取的方式是,用函数取得密钥的句柄(智能指针,标识由系统分配,不直接指向内存),并只传递句柄,最后由一个关键的函数读取密钥,如果中间过程中某个函数被攻破,那么攻击者也只能获得密钥的句柄,而不能直接获得密钥。
三是密钥交换要谨慎。密钥交换一直是一个令人头疼的问题,如果攻击者能够威胁密钥交换的过程,TA就有可能获得密钥,并破解整个系统。密钥交换过程中面临的两大威胁是信息泄露和信息篡改。如果密钥用来验证终端的身份,或者用来对某些数据进行签名,这两种威胁都能导致加密系统的失效。
因此我们在交换密钥时,应注意以下几点:(1)某些密钥绝对不能交换。进行数据签名的密钥是私有的,还有其他一些私有密钥也不需要与别人共享。(2)不要将密钥嵌入代码。嵌入代码的密钥确实不存在交换的问题,但是如前文所述,一旦被攻击者锁定位置,那么问题就严重了。(3)该使用人工时还是要使用。土办法有时比网络传输来的更加靠谱,虽然其成本会略显高昂,但在一个系统的安全性成本高于人力运输成本时,就应该这么做。(4)使用可执行密钥交换的协议,这样就可以在本地进行密钥的生成,无需进行传输。这个方法只适合短期或临时性的密钥。如SSL/TLS何IPSec在通信前进行密钥交换,而在交换完成后,传输的大量数据就无需再进行密钥交换。如果数据保存在注册表或数据库中,就不能使用这个模式。(5)不要创建自己的密钥交换协议。除非你是世界级的大神,创建自己的密钥交换协议来保护十分重要的数据是十分危险的,建议使用已有的成熟交换协议,如Diffe-Hellman协议,RSA等。
6、使用哈希值校验数据完整性
使用网络传输数据的时候,可以哈希值来确保数据的有效性,以防止数据被篡改,以及某些恶意和非法的数据提交。
哈希值是一种数据“指纹”,其基本原理是,通过散列函数,将一串数据压缩成摘要,使得数据量变小(当然,如果不压缩也是可以的,但最重的哈希值长度将非常长)。并用函数将数据打乱混合,重新创建一个哈希值(又被称为散列值,hash values,hash codes,hash sums,或hashes)。散列值通常用一个短的随机字母和数字组成的字符串来代表。哈希值取决于一段数据中每个可能的位置的值,因此,理论上,修改任意一个地方都会引起哈希值的改变。但由于压缩的应用,哈希值会出现冲突(即2个不同的值,最重哈希值会是相同的)。好的散列函数在输入域中极少出现散列冲突。
举个简单的生成哈希值的例子,这里我们不用压缩,只打乱次序。我们要取得一个字符串“abmk”的哈希值,首先,我们找到a、b、m、k的ASCII字符,分别是:61、62、6D、6B,然后我们将其打乱,将第3个字符m拉到最前面,ASCII码的次序变成:6D、61、62、6B,然后,我们采取一个简单的算法,即当前位的哈希值为前一位ASCII码与当前位的ASCII码的十六进制和,第一位则保持原样,于是我们就得到下面这个序列:6D、CE(6D+61)、C3(61+62)、CD(62+6B),“6DCEC3CD”就是一串哈希值。
当然,这个例子讲述的是很简单的办法。一些较流行的哈希算法如MD5会进行补位、压缩等操作。由于存在MD5数据库,因此,我们在使用MD5等流行的加密算法时,一定要对其进行适当的变更,如增加任意字符串混进结果、3MD5甚至4MD5等。当然,对安全要求高的企业用系统还是尽量避免使用MD5算法,而采用RSA等强度更高的算法。
现在,我们来看看如何利用哈希值校验数据。例如,我们要向一个接口传输一些参数,“id”参数的值为“120”,“number”参数的值为“5”,“token”参数的值为“cbadfaec”,我在本地将参数传递给接口服务器的同时,还传递一个哈希值参数“hashcode”,其算法是:先把参数名按字母顺序排列,然后使用“&”连接它们,再利用等号将键值连接,再使用1次MD5加密,于是,我们需要传输到服务器的值是:id=120&number=5&token=cbadfaec&hascode=b564e4de8f2c7fc38f44facd77cbe534。服务器端在收到这串数据后,将会对hashcode参数外的其他3个参数进行同样的算法,将得到的哈希值与传递的哈希值进行比对,相同则允许进行操作。
另一个利用哈希值校验的常见场景是,将用户的密码以哈希值的方式存储在服务器端的数据库上。在验证时,将用户输入的密码的哈希值与服务器的进行比对,比对成功则予以授权。
7、使用数字签名
数字签名将哈希值与加密相结合,以确保数据的完整性,并验证数据发送方的身份。
使用数字签名加密的大致步骤如下:首先,将数据转换为哈希值,然后,使用用户私钥加密哈希值,由此生成数字签名,并将此签名与数据一同发送到接收方(如一台服务器)。
解密的大致步骤如下:首先,接收方使用发送方的公钥进行签名解密,得到原来的哈希值。如果可以解密,则说明数据来源于可信方(即私钥所有者)。然后,对其他的数据运行哈希算法得到哈希值,并将其与解密出的哈希值进行比对,如果两个哈希值相同,则可以确信数据没有被篡改。
二、数字证书
数字证书可以使不对称加密、公钥交换更加的安全,从而保护Web应用程序。数字证书是将个人和单位的详细信息,与个人或单位的公钥绑定的信息项,可用数字证书确认客户端和服务器的身份。
1、基本定义
数字证书是包含公钥持有者信息的二进制结构,最通用的证书是X.509证书,它有3个版本:1、2、3。以X.509的版本3为例,它至少包含了下表中列出的信息:
项 目 | 描 述 |
---|---|
版本号 | 数字0、1、2,分别对应1、2、3证书版本 |
序列号 | 由证书颁发者确定的证书的唯一标识符 |
签名算法 | 产生数字签名的算法,用对象标识符(OID,Object Identifier)表示 |
颁发者名称 | 证书颁发者名称,用X.500名称表示 |
有效期 | 证书有效的时间段 |
主题名称 | 主题名称(私钥的所有者,该所有者与证书中的公钥有关),用X.500表示 |
主题公钥信息 | 创建公钥/私钥对的算法(用OID表示),以及实际的公钥数据 |
证书数据的哈希值 | 证书中的散列化内容,用颁发者的私钥对这些内容加密后会得到数字签名 |
使用数字证书的一些通用协议包括:
- SSL/TLS。用来保护客户端应用程序和服务器应用程序之间连接安全的协议
- 安全多用途Internet电子邮件扩展(S/MIME,Secure Multipurpose Internet Mail Extensions)。用来发送安全的电子邮件。
- IPSec。支持保密性、身份验证和数据完整性的计算机之间的协议
2、证书颁发机构
数字证书由证书机构颁发,这个机构是众所周知的受信任的第三方,它的职责是确认证书的内容和所有权。证书颁发机构向一个主体颁发证书时,会完成以下步骤:
- 进行背景检查来确认主体的真实身份。例如,对物理地址的检查,或者对主体发送过来的电子邮件进行检查。检查的过程也可能只是简单的确认一下,但由于证书通常用在重要敏感的地方,所以更严格的背景检查是明智的。
- 使用私钥创建证书并签名
- 颁发证书给主体
- 让所有感兴趣的用户知道该证书(这一步也可以由主体来完成)
而在用户这边,可以自由的选择信任哪些证书颁发机构,这往往取决于以下几个因素:
- 证书颁发机构自身的权威性。
- 证书颁发机构为确认主体身份进行的各种检查。这个检查过程必须公开,使用户可以确定对该机构颁发的证书的信任程度。
- 证书本身的种类。这个指标反映了颁发机构所提供的担保等级。例如,只浏览某个网页的证书的等级会低于网银系统的证书等级。如果两个实体信任同一个证书机构,它们就可以交换证书以获得彼此的公钥,从此,这两个实体可以确保相互之间的安全传输。
3、证书链和层次结构
与根证书相连的一系列证书称为叶子证书,这些叶子证书和根证书一起,组成了证书链和等级结构。根证书是等级结构最顶层(也可以说是最基层)的证书,它也被称为自签名证书,因为它是证书颁发机构颁发给自己的证书。
通常情况下,根证书会颁发多个下级证书,下级证书再颁发下级证书。下级证书可以基于不同的部门、地理位置或证书用途(如客户端验证或服务器端验证)。
为了使数字证书生效,证书用户必须高度信任这些证书。但有些时候,用户并不是十分相信这些证书颁发者。如果用户不知道这个证书颁发机构,可能只会勉强的接受该机构颁发的证书,也可能不信任该证书。这个问题可以在信任过程中,通过信任等级结构解决。
信任等级结构是指,信任过程至少要从一家可信任的授权机构开始。这个权威机构可能是政府的某个代理,或是独角兽级别的大公司,它被称为“根权威机构”。根权威机构可以认证其他证书颁发机构(称为第一层证书颁发机构),然后这些第一层颁发机构可以接着颁发证书,也可以认证其他机构为第二层颁发机构。
4、证书的存储
在浏览器所能访问的证书存储区中,存放着客户端证书和服务器证书。证书存储区是一个永久存储的位置,如某个磁盘位置或注册表,可以在系统内存中创建和开放证书存储区。内存存储区提供临时的证书存储区,用来保存不需要永久保存的证书。证书存储区包括下列信息:
- 证书。
- 证书撤销列表(CRL,Certificate Revocation List),是由证书颁发机构保留和发布的文档,该文档列出证书颁发机构颁发的但已经无效的证书。
- 证书信任列表(CTL,Certificate Trust List),是一个预定义列表,其中的项目经过了受信任实体的签名。表中所有项目都经过签名实体验证和认可。
系统存储区是由一个或多个预定义的物理存储区组成的存储区集合,它包括以下类型:
- 个人存储区。个人存储区包括某个用户的证书。个人存储区可位于多种物理位置中的任一位置,包括本地或远程计算机中的注册表、磁盘文件、数据库、目录服务、智能卡或其他位置。虽然任何证书都可以存储在个人存储区中,但这个存储区理应只存储个人证书。浏览器一般使用当前系统用户的个人存储区,而服务器软件则使用本地计算机系统的个人存储区。
- 受信任存储区(其他存储区)。这个存储区包括你信任的人的证书,当某个人的证书放到此区域后,将不再提示你确认是否信任此人。
- 根存储区。受信任的证书颁发者的证书通常保存在根存储区(注册表子键)。根存储区是受保护的,用户应只在其中存储受信任的证书。在企业环境中,管理员可以将证书从域控制器复制到客户端计算机的根存储区,该过程可向域的所有成员提供相似的信任列表。
- CA存储区。CA存储区包括可信任的CA颁发的证书。需要拥有CA的证书来建立证书链,使用户可以信任此CA颁发的所有证书。
除了这些预定义的存储区,也可以使用用户定义存储区存放证书信息。
在Windows系统中,微软还提供了.net Framework SDK的证书管理工具Certmgr.exe,此工具可以进行一系列的证书管理。
5、获取个人证书
为了保护电子邮件的安全性,个人可以向商业证书颁发机构(比如VeriSign)购买个人证书,然后可以对邮件进行加密,或者进行数字签名,以证明邮件的真实性,或向WEB应用程序标明自己的身份。在购买证书,并将其对邮件进行加密或签名后,信息接收方可以确认信息在传送的过程中没有被篡改,并且它来自于你(前提是信息接收方信任证书颁发机构)。
那么如何获取个人证书呢?有两种类型的证书颁发机构(CA):企业和个人。两种CA都有公开的网站用来开放申请,并提供证书申请向导,在申请成功后,根据提示安装自己的证书即可。如果是Windows系统,企业CA还可以使用Active Directory目录服务,来向企业内部的员工颁发个人证书。
个人可以使用证书向导生成CSR(证书签名申请,Certificate Signing Request),然后提交给CA来获取证书。CSR生成步骤如下:
- 在证书MMC(控制台)中,展开“控制台根”节点,然后展开“证书”文件夹。
- 右击“个人”文件夹,指向“所有服务”,然后单击“申请新证书”。
- 证书申请向导引导你按步骤申请证书,需要依次指定证书模板、加密服务提供者、证书颁发机构、证书的通俗名称和描述。
Windows系统下,.net Framework SDK的工具Makecert.exe可以用来创建证书,但是它生成的证书只能用来测试。此工具创建用于数字签名的公钥/私钥对,并将其存储在证书文件中。此工具还将密钥对和某个指定的发布者相关联,并创建X.509证书,该证书将用户指定的名称与密钥对的公共部分绑定。
6、获取服务器证书
服务器证书安装在Web服务器上,服务器证书对发送给客户端浏览器的信息进行加密,并解密从浏览器接收的信息。
为获得服务器证书,需要证书颁发机构(CA)的站点提交CSR。CA确认你的公司是有效的后,向你颁发服务器证书,然后就可以将此证书安装到Web服务器上。需要注意的是,用户如果连接上你的网站,也必须安装该CA的根证书,否则就会看到该证书不可信任的安全性对话框,需要用户手动去选择信任。
不同的CA,其证书申请过程可能有差异。现在的可信CA,颁发的证书一般都是收费的,随着强度的不同,国内的证书价格一般以500元左右/年起步,随着强度和CA授予的可信级别的不同,价格相差比较大。这里大致介绍下向CA申请证书的步骤。
- 使用Web服务器证书向导生成CSR。CSR创建私钥/公钥对,并将其保存在扩展名为.csr的文件中。建议备份此.csr文件,因为这是私钥的唯一副本。
访问CA的站点,并提交生成的CSR。在本地使用记事本(不要用Word这样带有格式的文本编辑器)打开CSR文件,然后选中以下列文字为开头(包含下列文字):
- --BEGIN NEW CERTIFICATE REQUEST--
并以如下文字结束(包含)的字符串:
- --END NEW CERTIFICATE REQUEST--
复制选中的文本,然后将其粘贴到CA的联机登记表中。
- 将此申请与必需的身份标识凭据一起发送给CA。CA接收到此申请时,会确认这些凭据并颁发证书。
- 定期访问CA的站点,检查的申请是否通过。申请通过后,可以从CA的站点下载证书文件。这里建议下载后做一个备份以防丢失。
- 最后,通过Web服务器证书向导安装此证书即可。
在Web服务器上安装证书会启用Web服务器的SSL端口,一般为443端口。启用SSL端口后,用户可以访问Web服务器上的所有页面,但原来的http://开头的网址,会变成https://开头。
注意:本页面内容为W3xue原创,未经授权禁止转载,违者必究!
来源:W3xue 发布时间:2018/3/15 13:36:14