网络加密的需求
1、网络流量加密的目的在于防止嗅探(偷听)、数据注入以及会话劫持;
2、在IP网络中数据是端对端传输的,为什么还存在信息嗅探那么一说?
a> 在无线网络环境中,无论是频分复用(如wifi)还是码分复用(如CDMA),由于信道是复用的,数据包都是可以被第三方拿到的;在hub环境中就更是如此了,甚至解复用都不用了;
b> MAC flooding。在Switch组建的有线局域网环境中,由于Switch级联的情况存在,所以一个口上可能会有多个MAC(Media Access Control)地址连接过来。攻击者可能通过MAC flooding的方式把Switch降级为hub(hub工作在网络第一层,不认得MAC,所以只会广播);
c> MAC duplication。有些网卡支持多路径连接到同一个Switch(用以增加带宽和冗余),这样在某些模式下交换机就不能自动将端口和MAC绑定了;此时攻击者简单地伪造MAC就有可能可以达到嗅探的目的;
d> ARP攻击,浑淆网络中IP和MAC的绑定关系,这是常用的嗅探手段;
3、如何防御ARP攻击?
a> ARP用于在MAC地址和IP地址间建立关系,工作在网络第2层;
b> 朴素点的防御方法就是用静态ARP(www.linuxidc.com作为只用认识网关的单台服务器而言,这办法物廉价美);
c> 华丽点的办法是使用ARPTables(http://en.wikipedia.org/wiki/Arptables);
d> 有些交换机支持在端口上绑定MAC,这不但可以防御ARP攻击,同样也可以防御MAC flooding和MAC duplication;
4、vice versa —— 反之亦然;
5、加密能帮我们达到什么目标?
a> 加密可以帮助我们实现验证和保密,但是攻击者还是可以知道信息被发送出去了,有时候通过流量分析的手段,攻击者还是能获得一些有用的信息;
b> 加密未必就一定能同时实现验证,但是良好的设计一般是同时实现的(http://zh.wikipedia.org/wiki/%E5%9D%97%E5%AF%86%E7%A0%81%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F#.E8.AE.A4.E8.AF.81.E5.8A.A0.E5.AF.86);
c> 做好通信加密的同时,别忘记如果主机本身攻破,那还是一切都完了;
6、柯克霍夫原则(Kerckhoffs’s principle):
“除了密钥之外的所有东西(数据包和加密算法)都被攻击者得知了,攻击者也不能得知通信内容。因为加密必须防住它的发明者,而且发明新算法比发明新密钥难多了。”,
类似的还有香农箴言:
“敌人知道系统。(The enemy knows the system)”;
7、身份验证和完整性检查比加密更重要(后者只是获得信息,前者获得权力),同时别忘记防御重放攻击和阻断攻击的威胁;
8、OpenSSL套件:
a> libcrypto。提供加密功能,bind、OpenSSH、Cyrus SASL有用到;
b> libssl。提供加密信道TLS(Transport Layer Security)/SSL(Security Socket Layer)功能Sendmail、OpenLDAP、Apache、IMAP等有用到;
c> openssl。一个生成密钥和手动加密的命令行工具;
d> GNUTLS、NSS(Networks Services Software)是它的竞争对手;
1、对称加密:
a> 顾名思义,通信双方用同一个key给信息加密解密。效率高,问题在于如何传递密钥(防止嗅探)是个问题,尤其是更换密钥的时候;
b> 对称加密算法有:DES、DES3、AES、Blowfish、Twofish、RC6、Serpent、IDEA、CAST5等;
c> 算法一般只能加密固定长度的数据,要应用到实际程序中外面还要包装一层“块加密模式”,就是把变长的数据给切开加密了,这模式就叫ECB(Electronic codebook),它的弱点在于一样明文会加密出同样的密文来,那样就可以用流量分析来破解了。另一种叫做CBC(Cipher-block chaining)的模式则避免了这个弱点,它使用加密后的前一个块异或后一个块。此外还有PCBC、CFB、OFB、CTR等模式(http://zh.wikipedia.org/wiki/%E5%9D%97%E5%AF%86%E7%A0%81%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%A8%A1%E5%BC%8F)。千万别傻乎乎地去写这些模式(我就傻了一次?),各种语言的官方库里都有现成的;
d> 可用工具:gpg、openssl(openssl enc、man enc);
2、加密哈希(摘要算法):
a> 把不固定长度的明文弄成固定长度的密文。不可逆,由密文无法还原出明文。不同的明文会得出不同的密文;
b> 多用于存储密码和完整性检查;
c> 常用的摘要算法有CRC32(命令行cksum)、MD5、SHA1等。CRC32已经是不安全的算法了,只有一些很老的程序在使用。MD5是目前最常用的摘要算法,它的速度非常快。最新的程序已经开始使用SHA1算法,它比MD5慢,但是会稍稍提高安全性(MD5已经被认可冲撞可计算);
d> 当然cksum、md5sum、sha1sum可以提供这些算法,还有一个更灵活的工具是openssl dgst(openssl dgst -sha1 /etc/passwd);
3、消息认证码(MAC:Message Authentication Code):
a> 有key参与的摘要算法,把不固定长度的明文弄成固定长度的密文。不可逆,由密文无法还原出明文。不同的明文会得出不同的密文;可以大概理解为带salt的MD5(其实不同),这个salt是通信双方都知道的;
b> 用于网络通信的完整性检查;
c> 一个产生MAC码的方法是这样的,用CBC模式对消息进行加密,把加密出来的最后一个块当作MAC。因为CBC是Chain的,所以一点内容的改变都会造成最后一个块的改变。使用这种方法要避免几个容易犯的错误,最常见的就是把用于CBC加密和CBC-MAC校验的key用成同一个,这很危险;
d> 另一个更简单的方法是直接使用现成的MAC算法,如RFC2104介绍的HMAC算法。它经常和MD5、SHA1结合起来一起用(http://en.wikipedia.org/wiki/Message_authentication_code);
4、不对称加密(公钥算法):
a> 分为公钥和私钥,任何一个钥匙加密都要用另一个钥匙去解密(一般是公钥加密,私钥解密),这就解决了密钥分发的问题;
b> 公钥算法有RSA、DSA(只为数字签名而设计)、ElGamal等,最常用的就是RSA(RSA vs DSA http://lists.gnupg.org/pipermail/gnupg-users/2006-June/028808.html)。
c> RSA规定了最多可加密数据的长度,而且公钥算法比对称加密算法要慢很多。所以比较通用的使用方法是——使用公钥算法完成对称加密的key的分发工作,随后的通信用对称加密算法来保障;
d> 常用工具:gpg、openssl rsautl;
1、用户验证:
a> 这是摘要算法被广泛应用的一个场合,这样就不用存储用户的明文密码了;
b> 原始的UNIX密码是使用的基于DES的摘要算法,在现代的标准来看已经不安全了。Linux采用了FreeBSD开发的基于MD5的摘要算法(现在也不安全了??);
c> 记得加salt,而且不同的用户要用不同的salt,这样同样的明文不会hash出相同的值(另外,用户密码独立于用户信息存储是个好设计);
d> openssl passwd(man sslpasswd)可以帮助我们产生Linux式的密码(/etc/shadow);
2、数字签名:
a> 数字签名使用公钥算法的消息认证码(MAC);
b> 它和公钥加密是反着的——私钥加密,公钥解密(加密是公钥加密私钥解密);
c> 为了速度的考虑(非对称算法很慢),一般会将消息先行hash摘要过后再对摘要进行签名;
d> DSA(Digital Signature Algorithm)或叫DSS(Digital Signature Standard)是一个只能用于签名的公钥算法,它是美国国家安全局在RSA还在专利期内的时候专门为美国国家标准技术研究所开发的;
e> ElGamal和RSA既可以用于签名也可以用于加密;
3、key的分发:
a> 迪菲-赫尔曼密钥交换(Diffie–Hellman key exchange,简称“D–H”)是最初被发明的可以让双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥的算法。但是由于攻击者还是可以干预密钥创建前的信息交换,所以DH一般要和DSA或RSA一起使用,目的是对消息进行认证;
b> 另一种方法是干脆使用RSA不对称加密来交换对称加密的密钥;
c> 以上两种方法都还有一个问题需要解决,那就是如何认证客户端最开始拿到的公钥确实是服务器端的公钥呢?这个问题可以交由数字证书去完成;
4、数字证书:
a> 通信的双方共同信任一个第三方(CA,Certificate Authority),CA自己的证书是自签名的;
b> 一个数字证书包含以下内容:要分发的公钥、此公钥的hash以及此hash用CA的私钥签名后的值、过期时间、公钥拥有者的信息、证书用途的信息、CA自身的信息,前两项就可以保证公钥的合法性。因为用CA的公钥可以验证hash是没问题的,然后hash没问题就说明了要分发的公钥没问题;
c> TLS证书使用X.509数字证书标准格式。发行者和证书拥有者的唯一标识使用X.500目录服务的命名法;
d> 还有另一种公钥分发模型,用“信任网络”取代了CA的角色。在这种模型里面,每个人都可以为别人签发数字证书,然后每个人选一个自己确实信任的节点作为自己信任的CA,然后展开信任关系。这种公钥分发模型为OpenPGP所用;
5、TLS(Transport Layer Security)和SSL(Secure Socket Layer)
a> TLS/SSL是一套对称和不对称加密的混合系统,用慢的不对称加密传递对称加密的key之后,后面就一直用对称加密的key传输数据,这样快;
b> TLS/SSL的问题是服务器的身份被验证过,而客户端的身份却没有被验证。一般来说,客户端用别的办法获得服务器的信任(如输入用户名密码),但实际上客户端的TLS认证也是可行的,服务器端同样可以要求客户端在进入对称加密的阶段前发送自己的CA证书来认证身份(如果客户端很多的话要签发很多证书);
6、TLS握手过程:
a> Client向Server请求一个TLS连接,同时表明自己可以接受什么样的加密算法,完整性校验算法,想用什么样的key;
b> Server按照Client的请求回给Client一个数字证书,里面就包含了Server自己的公钥;
c> Client用CA的公钥验证数字证书的合法性,随后取得了Server的公钥;
d> Client生成对称加密要用的key,用Server的公钥加密后传给Server;
e> Server用自己的私钥解密,获得Client给它的key;
f> Client和Server开始用key和对称加密展开随后的交流;
7、给私钥配上密码好吗?
a> 确实能在一定程度上提高安全性,但是也会带来麻烦,这是一个折中的方案;
b> 自启动的服务没有私钥密码无法自动启动,想要解决这个问题,只能去掉公钥加密密码;
c> 私钥的加密只能采取对称加密算法,输入的密码是对称加密的key,这意味着这个key在系统的内存中是能被debug工具找出来的,因此这个密码阻挡不了高级的攻击者;
8、如何签发一个CA证书?
a> 想要获得一个CA证书,首先要创建一个CSR(Certificate Signing Request)。其中应该包含除了CA用它的私钥算出来的那个hash的签名之外所有的信息,包括你要分发的公钥(注意别包含私钥),你的认证信息等内容。然后把这一切发给CA,让CA去签名;
b> 这些信息要用范轨的形式(X.500/X.509)书写,openssl req能帮我做好这件事;
c> CA拿到CSR后验证身份确实和填写的身份符合,就签一个名,证书就做好了。证书会给申请者一份,以后的通信就和不和CA打交道了。CA自己也会留一份副本,用于以后撤销证书(撤销证书只能等客户端来主动更新信息)时使用;
d> openssl ca能帮我们把CSR签发成CA证书。它还能帮我们管理多个证书的结构,弄成一个简单的CA中心;
9、CA证书的过期:
a> 数字证书都有实效性,一般而言CA签发的证书1年或2年过期,而内部签发的证书可能会很短(短到1-2小时都有可能);
b> 证书的过期主要是为了让公钥过期,这样对应的私钥也就过期了。这样即使万一私钥被盗取了,也会在过期时间过后变得不可用(过期时间内是没有办法的);
c> 更短的过期时间提供对私钥更好的保护,但管理起来更麻烦。反之亦然;
d> 注意一下在新旧证书切换时,留出一段新旧证书同时运行的重叠期,以让客户端平滑过渡;
10、CA证书的作废:
a> 证书地作废主要也是为了保护用户的私钥。但证书的作废是件很难的事,主要的麻烦是CA很难主动通知到每个客户;
b> TLS/SSL使用的解决方案是CA生成一个包含所有作废证书的CRL(Certificate Revocation List),然后客户端定时地下载CRL,这样客户端就能知道证书作废地情况了。但实际情况是很多客户端压根就不去下载CRL,所以作废证书会继续生效到过期时间之前;
c> openssl ca -revoke可以帮我们作废证书, openssl ca -gencrl可以帮我们生成CRL,有些客户端(如Mozilla)要求DER(Distinguished Encoding Rules)而非PEM(Privacy Enhanced Mail)格式的CRL,openssl也可以帮我们做转换;
d> 另一种被Kerberos采用的解决方案是——给证书签发很短很短的过期时间(几小时),这样作废的证书只要不续签就会在很短的时间内自然过期;
11、数字证书体系在应用上仍有不足(重要性排序):
a> 用户大多只会看证书的签发中心,不会仔细校验证书大篇幅的相关信息,这是一漏洞;
b> CRL难以分发;
c> CA中心一旦被侵入或者失误,签发了错误的证书,后果严重;
d> 由于CA中心都内置在客户端里,自建的CA中心会弹出不友好的提示信息。且默认只是引导用户信任证书。若要信任CA中心需要手动添加;
e> 还要注意的是,数字证书只是用于验证,授权要记得一定自己另弄一套;
其它
1、GnuPG(gpg)是个好工具,可以用于手工加密信息,也可以跟一些开源邮件客户端一起结合起来使用,保证信息安全;