互联网安全设计剑与盾
前言
互联网是软件厂家求生之地,自然也险象环生。要保证企业生存发展,自身软件的安全是最重要的,要能够保护软硬件的可用,数据的安全。
互联网的攻击(剑)
目前互联网常见的攻击方式如下:
-
XSS攻击
XSS攻击的全称是跨站脚本攻击(Cross Site Scripting),为不跟层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS
-
CSRF攻击
CSRF全称是跨站请求伪造(cross site request forgery),CSRF伪装受信任用户,向第三方平台发送恶意请求
-
SQL注入攻击
所谓SQL注入攻击就是将一些恶意SQL执行指令伪装成SQL参数传给DBMS,然后执行恶意攻击
-
DDos攻击
DDos(Distributed Denial of Service),即分布式拒绝服务攻击,DDos攻击是基于Dos发展来的。什么是Dos呢?首先简单介绍一下Dos,Dos就是利用信任的客户端向服务端频繁发送请求,从而达到服务器处理不过来,请求超时。所以Dos其实就是一对一的,在邮件设施还不太好的情况是有效的,对于性能极佳的服务器压根不管用了,所以就有了DDos,分布式拒绝服务攻击。
-
0day
所谓“0Day漏洞”,是指那些没有公开过,因而也没有补丁的漏洞,也就是通常所说的“未公开漏洞”。
-
其他
攻击手段应该说只有你想不到,没有做不到了。
厂家们的防守(盾)
首先网络攻击行为都是违法的,如果有了实质性的证据或者造成比较大的损失是需要追究到底。有了攻击,自然作为厂家我们需要防守。其中分为两部分,有一些是需要系统、中间件或者第三方的漏洞修复,比如0day是系统,DDos需要我们的服务托管商。另外一部分我们可以在系统设计的时候就考虑到并且进行防范。那我们能够或者应该考虑的安全防范措施有哪些呢,下面来对一些方法和概念进行说明。
HTTPS
我们有时会看到有一些服务的升级是说“全站升级为https服务”,https具体是什么意思呢。
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer 或 Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。网景在1994年创建了HTTPS。
讲到HTTPS就必须说要SSL,根据上面的说明实际上HTTPS就是HTTP+SSL。
HTTP(HyperText Transfer Protocol)协议是基于TCP的应用层协议,它不关心数据传输的细节,主要是用来规定客户端和服务端的数据传输格式,最初是用来向客户端传输HTML页面的内容。默认端口是80。目前最新的HTTP版本为2.0,但是更常用的是1.1[1]。
HTTPS的作用主要有2点:
-
建立一个安全通道,用于保证数据传输的安全性
-
确认网站的真实性
而HTTPS之所以是最基础(可靠)的安全手段,原因来自于证书颁发机构(CA, Certificate Authority)提供的安全证书,证书级别也分为几类如DV SSL 、 OV SSL 、EV SSL[2]。
HTTPS解决了HTTP在信息传输过程中明文传输了问题,而采用对称加密来处理传输的信息。所以安全的第一步,请开启全站的HTTPS。
而且在开启了HTTPS的网站上,浏览器默认是不允许访问HTTP协议的内容。
加密/解密
按理说我们已经开启了HTTPS,不应该已经是加密的状态了么,为什么我们接着就讨论加密这个问题?
实际上HTTPS加密的是基于底层TCP传输的过程,客户端和服务端实际上还是能够抓到未加密的内容,我们要完全解决这个问题,在一些重要信息的交互还是需要引入加密的概念。
加密算法分为两种:
-
对称加密算法:密钥只有一个,加解密均使用相同密钥。
-
非对称加密算法:分为公私钥,加密使用公钥解密使用私钥,或者反之
可能有人问MD5或者Base64算不算加密算法?
不算,加密算法是要求明文通过一定的计算生成不同的格式,其他人无法还原,但是接收人是可以还原的。MD5不可逆,Base64是用文本表示二进制的编码方式,它使用4个字节的文本来表示3个字节的原始二进制数据,实际上算法是公开的,任何人拿到都可解。
乍一看非对称加密算法的安全性更高啊,为什么我们直接选择它就好啦。实际上非对称加密算法的安全性更高,但是效率也相对较差。能够差到什么地步呢?有测试数据,使用 AES CBC 模式 和 RSA 256 对长度为160 bytes 的明文进行加密10000次,AES耗时130ms,RSA耗时193000ms(3.2分钟),所以我们实际生产中,并不是盲目选择,而且根据自己的实际情况选择合理的算法。
数字信封
如何整合这两种算法的优势?
PKCS#7[3]中将数字信封作为术语进行定义,而在正文中对进行了如下解释:数字信封包含被加密的内容和被加密的用于加密该内容的密钥。
在数字信封中,信息发送方采用对称密钥来加密信息内容,然后将此对称密钥用接收方的公开密钥来加密(这部分称数字信封)之后,将它和加密后的信息一起发送给接收方,接收方先用相应的私有密钥打开数字信封,得到对称密钥,然后使用对称密钥解开加密信息。
对称加密算法:AES、DES、TripleDES、RC2、RC4、RC5和Blowfish等
非对称加密算法:RSA、Elgamal、背包算法、Rabin、D-H、ECC等
目前最流行的方案就是AES+RSA,首先生成公私钥,公钥对外公布,在每次发起请求时生成AES的密钥,并且用RSA私钥加密之后附加至请求。对方在获取到请求时,首先用公钥解密出AES的密钥,然后用密钥解密传输内容。反之亦然。
加签/验签
加签其实就是加入签名的意思,验签就是验证签名的意思,和加密/解密之间一样吗,有没有什么关联?
答案是不一样,加入签名的目的实际上和我们现实生活中一样,为了确保请求的真实性(不是伪造)。举例一个场景:我在网上商城购物买了一件价格100元的衣服,但是有恶意程序拦截了我的请求并且将数量改为100件提交。从服务端的角度来看数据完全没有任何问题,于是就写入了这笔订单。但是实际上提交的数据被篡改了!为了避免类似的情况,我们会在请求生成时,同时使用特殊的算法对所有提交的参数用某种算法生成一个字符串作为签名,服务端获取到请求后用同样的算法对所有参数进行计算,然后比对签名是否相同来判断提交参数是否有被篡改过。
签名参数常用的名称为signatrue或者sign。
我们以微信支付的签名算法为例子:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
这样在进行包拦截时不知道加密算法,即使篡改了请求也会被服务端以签名验证失败的理由拒绝。(如果知道了加密算法直接构造请求就好也不用拦截了)。
加签/验签可能会应用在所有的接口访问中,所以我们希望这样的算法是非常高效的,在保证安全的前提下尽量减少对效率的影响。
常见的数字签名算法主要有RSA、DSA、ECDSA三种
1. RSA数字签名算法
-
MD2、MD4、MD5算法
-
SHA-1算法(在2017年2月23日Google宣布实现了对SHA-1算法的碰撞破解,并发布了具有相同hash值的两份不同pdf文档)
-
SHA-2算法(SHA-224、SHA-256、SHA-384和SHA-512并称为SHA-2)
-
SHA-3
2. DSA数字签名算法
3. ECDSA椭圆曲线数字签名算法
签名算法的破解
大家现在基本都听说过MD5和SHA-1被破解的事情,但是大家可能不一定都有了解其中的具体过程和含义。
2004年8月17日的美国加州圣巴巴拉的国际密码学会议(Crypto’2004)上,来自中国山东大学的王小云教授做了破译MD5、HAVAL-128、 MD4和RIPEMD算法的报告,公布了MD系列算法的破解结果。(注意:并非是真正的破解,只是加速了杂凑冲撞)2005年2月,王小云教授又破解了另一国际密码SHA-1。王小云的研究成果表明了从理论上讲电子签名可以伪造。
这段引用中报道的就是中国团队从理论上证明了签名算法是可以碰撞的,意思就是存在两段不同的内容可以计算出相同的MD5或者SHA-1的摘要值。
这对于某些应用场景是致命的,比如有些应用的密码就是使用MD5计算之后存储,那意味着有人知道你的密码MD5之后可以碰撞出和你密码完全不同的一段文字登录你的账号。
但是在某些场景可能影响就不一样了,比如Git使用的就是SHA-1的算法。Linus在得知SHA-1谷歌攻破时发表的看法如下:
git使用SHA-1主要是为了做错误检测,保证数据的完整性,对于信任问题,他说,他们的信任是基于人的,他不会因为某个特定的hash值就去信任某组数据。当然他也承认,在相当程度上,git也受益于SHA-1作为“信任工具”带来益处,所以攻破SHA-1对git确实有不良影响。
我们再回头看签名算法破解对我们做请求参数签名算法的影响有多大呢,其实我认为影响也是很小的。破解对于签名算法实际上意味着碰撞,我们其实是对一个有明确含义的数据结构进行摘要算法,如果只是给一个无意义的签名结果相同的字符串服务端同样会拒绝,并不会对业务造成任何影响。但是我也必须说明,更高安全等级的签名算法对我们是有正面意义的。
盐值
如果你无法切换签名算法,还有另外一种方式提高安全性,那就是盐值(SALT)。在计算MD5时,使用一个特殊的字符串加入计算过程,这样计算的结果就不是标准算法产物了。现在有一些密码破解是通过密码的MD5表查表进行比对,这样几乎就能避免被破解的可能性。
重放
重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。重放攻击可以由发起者,也可以由拦截并重发该数据的敌方进行。攻击者利用网络监听或者其他方式盗取认证凭据,之后再把它重新发给认证服务器。重放攻击在任何网络通过程中都可能发生,是计算机世界黑客常用的攻击方式之一。
重放有时可能不一定是攻击而且代码的漏洞(重复提交),但是造成的损失可能会很严重。目前比较流行的做法就是时间戳+唯一随机字符。
我们会要求客户端在提交请求时附带两个参数:timestamp和nonce,
-
timestamp:大家都知道是一个唯一的Long型数字,代表1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,我们接受到请求后会和服务端当前时间戳进行比较,超过一定时间范围(如60s内)直接拒绝。
-
nonce:Nonce是或Number once的缩写,在密码学中Nonce是一个只被使用一次的任意或非重复的随机数值。这个随机值我们会存在服务端的缓存中(如Redis),每次发起请求前都需要向服务端请求一个nonce,服务端会将nonce保存。服务端接收到请求后会验证nonce是否存在,如果存在就删除并且放行此次请求,如果不存在直接拒绝。
通过这两个参数就能避免请求包被录制和重放的可能性了。
CDN安全
大家现在的文档、图片、视频等基本都会托管到CDN来提高访问速度,所以我们也加上CDN的安全。CDN这边主要讲的还是访问控制,一般分为两类需求:
-
防盗链
-
复杂鉴权
防盗链
盗链的情况比较常见,CDN厂家是按照流量付费的。我将一张图片或视频上传至CDN,任何通过CDN提供的地址访问所消耗的流量都需要我付费。某个竞争对手的网址直接引用了我的CDN地址,造成我的费用流失我却没有任何收益。
所以CDN厂家一般都提供防盗链的措施,一般也有两种:
-
时间戳防盗链
-
Referer防盗链
时间戳就是生成一个临时链接,在一段时间内有效。每次想要查看对应文件时都需要通过接口获取最新的地址。
Referer是通过Http请求头当中的Referer字段,是否在指定的域名范围内。
这两种一旦发现异常情况也是直接拒绝请求。
复杂鉴权
业务方可能对于文件有鉴权特殊的判断要求,比如在我的APP内播放视频可以随时播放,而一旦将链接复制到外部我就要拒绝播放。
CDN场景一般还有提供称之为”回源鉴权“的方式
回源鉴权当然其中也会考虑请求超时等异常情况。
这样的方法结合我们自定义的nonce,就可以达到我们期望的效果了。
总结
以上基本就是架构设计过程中可以想到的针对安全方面涉及到的注意点,但是这一定不是固定不变的,根据实际的情况以及技术的发展我们的盾也要越来越坚实才行。
-
http版本演进
1.HTTP 0.9版本 1991年
这个版本就是最初用来向客户端传输HTML页面的,所以只有一个GET命令,然后服务器返回客户端一个HTML页面,不能是其他格式。利用这个版本完全可以构建一个简单的静态网站了。
2.HTTP 1.0版本 1996年
1.0版本是改变比较大的,奠定了现在HTTP协议的基础。这个版本的协议不仅可以传输HTML的文本页面,还可以传输其他二进制文件,例如图片、视频。而且还增加了现在常用的POST和HEAD命令。请求消息和响应消息也不是单一的了,规定了一些元数据字段。例如字符集、编码、状态响应码等。
3.HTTP 1.1版本 1997年
实际上是在1.0版本之后半年时间又发布了一个版本,这个版本在1.0版本的基础上更加完善了。这个版本增加了持久连接,就是说之前版本的协议一次请求就是一次TCP连接,请求完成后这个连接就关闭掉了。众所周知TCP协议是可靠的,建立连接需要3次握手,断开连接需要4次挥手,并且TCP有流量控制和拥塞控制,有慢开始机制,刚建立连接时传输比较慢,这是比较耗费资源的。一个丰富的页面会有许多图片、表单和超链接。这样的话就会有多次的HTTP请求,所以在这个版本上默认不关闭TCP连接也不用声明Connection: keep-alive字段。如果确实要关闭可以指定Connection: close字段。还引入了管道机制,就是说在一个TCP连接里可以同时发送多个HTTP请求,而不必等待上一个请求响应成功再发送。还增加了PUT、PATCH、HEAD、 OPTIONS、DELETE等命令,丰富了客户端和服务端交互动作。还增加了Host字段。
4.HTTP 2版本 2015年
这个版本也是随着互联网的发展,有了新的需求制定了新的功能还有对上一个版本的完善。1.1版本有了管道机制,但是正在服务端还是要对请求进行排队处理。这个版本可以多工的处理。还有了头信息压缩和服务器的主动推送。 ↩ -
证书类型
阿里云现提供4家主流的国际认证机构,其实通过阿里云进行证书的申请,可以理解为由阿里云代理,帮你申请证书。对于证书有单一域名和通配符域名证书,顾名思义,单一域名的证书,获取的证书只能验证指定的一个域名的安全性,但通配符域名(如.aa.com)所有的以.aa.com开始的域名都可以识别,当然这里面涉及到DV SSL 、 OV SSL 、EV SSL的概念,因为在买之前一定要知道这个概念的意义,否则钱花的会不知所然。
DV SSL
DV SSL证书是只验证网站域名所有权的简易型(Class 1级)SSL证书,可10分钟快速颁发,能起到加密传输的作用,但无法向用户证明网站的真实身份。
目前市面上的免费证书都是这个类型的,只是提供了对数据的加密,但是对提供证书的个人和机构的身份不做验证。
OV SSL
OV SSL,提供加密功能,对申请者做严格的身份审核验证,提供可信×××明。
和DV SSL的区别在于,OV SSL 提供了对个人或者机构的审核,能确认对方的身份,安全性更高。
所以这部分的证书申请是收费的~
EV SSL
超安=EV=最安全、最严格 超安EV SSL证书遵循全球统一的严格身份验证标准,是目前业界安全级别最高的顶级 (Class 4级)SSL证书。
金融证券、银行、第三方支付、网上商城等,重点强调网站安全、企业可信形象的网站,涉及交易支付、客户隐私信息和账号密码的传输。
这部分的验证要求最高,申请费用也是最贵的。 ↩ -
PKCS标准 Public-Key Cryptography Standards
RSA主导标准,RSA信息安全公司旗下的RSA实验室为了发扬公开密钥技术的使用,1990年开始便发展了一系列的公开密钥密码编译标准。只不过,虽然该标准具有相当大的象征性,也被信息界的产业所认同;但是,若RSA公司认为有必要,这些标准的内容仍然可能会更动。所幸,这些变动并不大;此外,这几年RSA公司也与其他组织(比较知名的有IETF、PKIX)将标准的制定通过standards track程序来达成。
PKCS#1:RSA加密标准。PKCS#1定义了RSA公钥函数的基本格式标准,特别是数字签名。它定义了数字签名如何计算,包括待签名数据和签名本身的格式;它也定义了PSA公/私钥的语法
PKCS#2:涉及了RSA的消息摘要加密,这已被并入PKCS#1中。
PKCS#3:Diffie-Hellman密钥协议标准。PKCS#3描述了一种实现Diffie- Hellman密钥协议的方法。
PKCS#4:最初是规定RSA密钥语法的,现已经被包含进PKCS#1中。
PKCS#5:基于口令的加密标准。PKCS#5描述了使用由口令生成的密钥来加密8位位组串并产生一个加密的8位位组串的方法。PKCS#5可以用于加密私钥,以便于密钥的安全传输(这在PKCS#8中描述)。
PKCS#6:扩展证书语法标准。PKCS#6定义了提供附加实体信息的X.509证书属性扩展的语法(当PKCS#6第一次发布时,X.509还不支持扩展。这些扩展因此被包括在X.509中)。
PKCS#7:密码消息语法标准。PKCS#7为使用密码算法的数据规定了通用语法,比如数字签名和数字信封。PKCS#7提供了许多格式选项,包括未加密或签名的格式化消息、已封装(加密)消息、已签名消息和既经过签名又经过加密的消息。
PKCS#8:私钥信息语法标准。PKCS#8定义了私钥信息语法和加密私钥语法,其中私钥加密使用了PKCS#5标准。
PKCS#9:可选属性类型。PKCS#9定义了PKCS#6扩展证书、PKCS#7数字签名消息、PKCS#8私钥信息和PKCS#10证书签名请求中要用到的可选属性类型。已定义的证书属性包括E-mail地址、无格式姓名、内容类型、消息摘要、签名时间、签名副本(counter signature)、质询口令字和扩展证书属性。
PKCS#10:证书请求语法标准。PKCS#10定义了证书请求的语法。证书请求包含了一个唯一识别名、公钥和可选的一组属性,它们一起被请求证书的实体签名(证书管理协议中的PKIX证书请求消息就是一个PKCS#10)。
PKCS#11:密码令牌接口标准。PKCS#11或“Cryptoki”为拥有密码信息(如加密密钥和证书)和执行密码学函数的单用户设备定义了一个应用程序接口(API)。智能卡就是实现Cryptoki的典型设备。注意:Cryptoki定义了密码函数接口,但并未指明设备具体如何实现这些函数。而且Cryptoki只说明了密码接口,并未定义对设备来说可能有用的其他接口,如访问设备的文件系统接口。
PKCS#12:个人信息交换语法标准。PKCS#12定义了个人身份信息(包括私钥、证书、各种秘密和扩展字段)的格式。PKCS#12有助于传输证书及对应的私钥,于是用户可以在不同设备间移动他们的个人身份信息。
PDCS#13:椭圆曲线密码标准。PKCS#13标准当前正在完善之中。它包括椭圆曲线参数的生成和验证、密钥生成和验证、数字签名和公钥加密,还有密钥协定,以及参数、密钥和方案标识的ASN.1语法。
PKCS#14:伪随机数产生标准。PKCS#14标准当前正在完善之中。为什么随机数生成也需要建立自己的标准呢?PKI中用到的许多基本的密码学函数,如密钥生成和Diffie-Hellman共享密钥协商,都需要使用随机数。然而,如果“随机数”不是随机的,而是取自一个可预测的取值集合,那么密码学函数就不再是绝对安全了,因为它的取值被限于一个缩小了的值域中。因此,安全伪随机数的生成对于PKI的安全极为关键。
PKCS#15:密码令牌信息语法标准。PKCS#15通过定义令牌上存储的密码对象的通用格式来增进密码令牌的互操作性。在实现PKCS#15的设备上存储的数据对于使用该设备的所有应用程序来说都是一样的,尽管实际上在内部实现时可能所用的格式不同。PKCS#15的实现扮演了翻译家的角色,它在卡的内部格式与应用程序支持的数据格式间进行转换。 ↩