TCP/IP 笔记 - 安全

安全:可扩展身份认证协议、IP安全协议、传输层安全、DNS安全、域名密钥识别邮件

任何由用户或以用户账号执行却违背了用户本身意愿的软件被称为恶意软件

网络安全是一门十分广泛及有深度的学识,而本书旨在了解TCP/IP协议族知识,所以书中只介绍了一些TCP/IP所使用的部分安全方案。并且对安全这块我也没多少深入的研究,也就基于书本内容做些知识摘抄以供了解和学习。

信息安全基础

从信息安全的角度看,无论是否在计算机网络中,信息都该具有一些属性:

  1. 机密性,信息只能为其指定的用户知晓。

  2. 完整性,信息在传输完成之前不能够通过未授权的方式修改。

  3. 可用性,在需要的使用信息是可用的。

  4. 可认证性,一个经过身份认证的组织或个体是不能够被其他个体假冒的。

  5. 不可抵赖性,一个个体做出的任何行为都能够在此之后得到证实。

  6. 可审计性,一些可信的日志或说明能够面试信息使用的过程。

前三者是重要的核心属性,又称'CIA三元组'。

根据[VK83],攻击通常被分为被动和主动两类。被动攻击一般会监视或窃听网络流量的内容,如果不加以控制,它将会导致信息未经授权就发布出去,这破坏了信息的机密性。主动攻击一般会篡改信息或使其拒绝服务,这破坏了信息的完整性和可用性。

被动攻击:

  窃听(机密性)

  流量分析(机密性)

主动攻击:

  消息流篡改(可认证性,完整性)

  拒绝服务DoS(可用性)

  伪造机构(可认证性)

通过加密机制,即可满足以上两种攻击的防御需求,通过加密后的数据不容易泄露信息内容、不容易破坏其完整性、也更安全的保障了可认证性。

基础的加密和相关知识

传统的基础加密主要用于保护信息的机密性,但其他属性如完整性和可认证性也能够借助加密以及相关的数学技术达到。下面的图说明了两个重要的加密算法:对称密钥和公开(非对称)密钥是如何工作的。

在对称密码系统中,由于加解密的算法相同,它们的密钥也是相同的。

在非对称密码系统中,每一个个体都拥有一对密钥,包括一个公钥和一个私钥。公钥是公开的,任何希望向这对私钥所有者发送消息的人都能够获得。公钥和私钥有数学上的关联,它们都是密钥生成算法的输出结果。如果不知道对称密码系统中的对称密钥或非对称密码系统中的私钥,任何第三方截获密文后都无法生成相应的明文。

对称密码算法通常被分为分组密码(或称块密码)与流密码两类。分组密码每次只对固定数目的比特块进行操作,而流密码将提供的大量比特作为输入并且会持续的运行下去。多年来流行的对称密码算法是数据加密标准(DES,是一种分组密码,使用64比特的数据块与56位的密钥)。该算法最终被认为不安全,后期采用3重DES利用两个或三个不同密钥对每一个数据块进行三次DES加密。但无论DES还是3DES,现在都逐渐被高级加密标准(AES)所取代[FIPS197]。AES针对不同版本所提供的密钥长度,如128位、192位、256位,于是就有了AES-128、AES-192、AES-256。

如上图,非对称密码算法存在一个问题:发送者使用接收者的公钥进行消息加密后发给接收者,那么只能拥有接收者私钥才能够对消息进行解密,然而这个消息不能保证是真实可靠的(因为任何人都能够发送这条消息给接收者)。于是基于非对称加密的公钥-密钥的关联性,非对称密码系统提供了另一项功能:对发送者进行认证。
该功能由将公钥加密和私钥解密反向操作而实现,如下图:

流行的公钥密码算法如RSA,在其初始化阶段,需要生成两个大素数p和q。这项工作首先需要随机地生成数值较大的奇数,后检验这些数是否为素数,直到找到两个大素数为止。两个素数的乘积 n = pq 被称为模。n,p,q的长度一般用比特来衡量。推荐n采用2048比特的长度,但通常情况下n为1024比特,p和q的长度为512比特。

根据RSA算法,n的构建方法为:

    Φ(n) = (q - 1)(p - 1)

Φ(n)的值表示n的欧拉数,是那些比n小且与n互质的正整数的个数。

根据Φ(n)的定义,选择RSA的公钥指数(称为e,表示加密),并按照关系式d = e(^-1)(modΦ(n))得到私钥指数(称为d,表示解密)作为乘法逆元素。为获取密文c,需要使用公式m = m(^e)(mod n)对明文m进行计算;反之则需要公式m = c(^d)(mod n)进行解密。一个RSA的公钥包含公钥指数e和模n,对应的私有则包含私钥指数d和模n。如果为了对一条消息m进行RSA数字签名,可以通过公式s = m(^d)(mod n)计算s的数值作为m的签名。任何接收到s的人能够使用公有元素e与公式m = s(^e)(mod n)进行检验,这样就能够验证生成数值s的是RSA的私有值d。RSA的安全性是基于对大数分解因数的困难性。

Diffie-Hellman-Merkle 密钥协商协议(DH)提供了一种解决"通信双方如何在窃听者不知情的情况下完成共同密钥协商"的计算方法,DH技术已用于许多与互联网相关的安全协议[RFC2631]。

DH的工作如下描述:

  1. 假设所有人都有相同的特征,并且知道两个证书p和q。p是一个(大)素数,g是模p的原根(g<p)。

  2. 基于1,集合Z(_p) = {1,...,p-1}中的每一个整数都能够通过不断地增加g来生成,也就是说对于任意一个证书n,必定存在倍数k使式子g(^k) ≡ n(mod p)成立。在给定g、n与p的情况下寻找合适的k值被认为是一件困难的事(离散对数问题),在给定g、k与p的情况下找出n是容易的。

建立一个共享的安全密钥过程如下(A和B之间):

  1. A选择一个秘密的随机数a,并按照公式 A = g(^a)(mod p)计算出A的值,然后将这个值发送给B;B选择一个秘密的随机数b,并按照公式 B = g(^b)(mod p)计算出B的值,然后将这个值发送给A。

  2. A将按照以下公式计算K值:K = B(^a)(mod p) = g(^ba)(mod p);B将按照以下公式计算K值:K = A(^b)(mod p) = g(^ab)(mod p)。

由于g(^ab)和g(^ba)是相等的,所以A和B都能获得协商密钥K。第三方窃听者只能获取g、p、A、B,因此在解决离散对数问题之前将无法获取密钥K。

在通信双方需要交换多条消息的场景中,通常会建立一个短期的会话密钥来进行对称加密。会话密钥一般由密钥派生函数(KDF)根据一些输入而生成的随机数,这些输入可能是一个主密钥或之前的会话密钥。如果一个密钥被破解,那么由该密钥加密的任何数据都会被破解,然而在一个持续的通信会话期间,往往会多次更改密钥。如果一种方案能够保证即使有一个会话密钥被破解而由其他密钥加密的后续通信过程仍然安全,那么就称该方案是完全正向保密(PFS)的。通常情况下能够提供完全正向保密的方案需要额外的密钥交换与认证过程,这样就引入了新的开销。

加密随机数是在密码协议中只使用一次的数值(又称临时密钥)。常用于认证协议,选择一个随机数或者伪随机数来保障时新性(时新性要求选取最新发生的消息或操作)。例如,在一个challenge-response协议中,服务器会为请求的客户端提供一个临时密钥,而客户端需要在指定时间内发送认证资料与临时密钥的副本作为响应。由于重放到服务器上的旧的认证交换信息不会包含正确的临时密钥数值,因此这种方法能够避免重放攻击。

混淆值是一个用于加密文本中的随机数或者伪随机数,可用于防御对密文的蛮力攻击(反复地猜测密码、口令、密钥或等效的秘密中并验证其是否正确)。

加密散列函数,类似于部分加密算法,用于做传输数据完整性的保障及预防对消息的篡改攻击。当一条消息M作为输入时,加密散列函数的输出H被称为这条消息的摘要或指纹H(M)。它不仅易于计算,还具有以下特征:

  1. 原像不可计算性,在给定摘要H(M)而未知消息M的情况下,难以得出消息M的值。

  2. 原像不相同性,给定消息M1的摘要H(M1),找出消息M2(M1 ≠ M2)使它的摘要与M1的摘要相等(H(M1) = H(M2))是十分困难的。

  3. 抗碰撞性,找出一堆摘要相同(H(M1) = H(M2))而自身不同的消息M1、M2(M1 ≠ M2)是十分困难的。

目前最通用的两个加密散列算法是生成128位摘要的消息摘要算法(MD5)和生成160位摘要的安全散列算法(SHA-1)。SHA-2基于一系列SHA函数,能够生成长度224,256,384,512位的摘要。

消息认证码(简称MAC或MIC),一般基于有密钥的加密散列函数,用于保障消息的完整性和防止各种伪造。这些函数类似于消息摘要算法,但需要一个私钥来验证消息的完整性,甚至也可能用于验证消息的发送者。给定有密钥的散列函数H(M,K),M为输入的消息,K是密钥,抵御"选择性伪造"意味着地方在不知道密钥K的情况下对指定的消息M生成散列值H(M,K)是非常困难的。消息认证码由于不止有一方知道对应的密钥,所以并不能为不可否认性提供坚实基础。

一个标准的使用加密散列函数的消息认证码被称为基于有密钥散列的消息认证码(HMAC),下面的公式定义了使用密钥K对消息M用H进行散列的方法(HMAC-H),它形成t字节的HMAC:

    HMAC-H(K,M)(^t) = Λ(_t)(H((K ⊕ opad) || H((K ⊕ ipad) || M)))

opad(外填充)是一个将数值0x5C重复|K|次的数组,ipad(内填充)是讲数值0x36重复|K|次的数组。⊕是向量的异或运算符,||是连接运算符,Λ(_t)表示取消息M最左边的t字节。其中的将一个散列函数作用于另一个散列函数的结构能够抵御所谓的扩展攻击,内填充与外填充的数值并不重要,但生成的2次密钥K1与K2需要有较大的区别。

随着消息认证码多年以来的发展,一些其他形式的消息认证码已经被标准化,比如基于密码的消息认证码CMAC、GMAC。这些新标准不使用HMAC的加密散列函数,而是使用分组密码,如AES。根据[RFC4493]描述,CMAC使用的是AES-128算法。GMAC则采用了AES算发的一种特殊模式,称为Galois/计数器模式,它仍然使用一个有密钥的散列函数(GHASH,并不是一个加密散列函数)。

证书相关知识

一种被称为"信任网络"的模型:通过一些当前用户(称为代言人)来做代言的方式以证明一个证书(身份-公钥对)的可靠性。一个代言人会对一个证书进行签名,然后将其发布出去,随着时间推移,如果一个证书有越来越多的代言人,那么它就越可靠。该模型是分散的、没有中心的权威机构,因此它具有一定的"草根"性。"信任网络"的优缺点显而易见,有点是其不存在中心的权威机构,模型不会因为单点失效而奔溃;缺点是新加入者需要经历相当长的时间才能使自己的密钥得到一定数量用户的代言。

一种更常见的方法是依靠中心化的机构,其中包括对公钥基础设施(PKI)的使用,PKI负责提供创建、吊销、分发以及更新密钥对证书的服务。它需要一些证书颁发机构(CA)才能运行,CA是用于管理与认证一些个体与它们的公钥间的绑定关系的实体。

ITU-T X.509 是公钥证书的格式标准[RFC5280],常见的的包括DER、PEM、PKCS#7、PKCS#12。

可用 openssl 命令来查看网站证书信息:

    openssl x509 -in xxx.pem -text

给出结构大致:

Certificate:  解码后的证书信息
    Data:  元数据
        Version:  版本,特定的证书类型
        Serial Number:  特定证书的序列号
    Signature Algorithm:  签名算法
        Issuer:  发行者,拥有以下特殊子域:C(国家)、L(地区或城市)、O(组织)、OU(组织单元)、ST(州或省)、CN(通用名称)
        Validity:  有效时间
            Not Brfore:  起始时间
            Not After:  结束时间
        Subject:  主题,标识与当前证书相关的实体
        Subject Public Key Info:  主题公钥信息,标识公钥的拥有者
            Public Key Algorithm:  公钥算法
                Public-Key:  公钥
                Modulus:  模
                    ...
                Exponent:  指数
    Signature Algorithm:  签名算法
        ...
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

# ... 根据字段决定值类型,代表密钥/签名等结果内容

在证书撤销的过程中,需要考虑一些问题'如何撤销证书?'、'如何让依赖方知道他们所依赖的证书不再可信?'。

为了验证某个证书,需要建立一条验证(或认证)路径,这条路径应当是一个已被验证过的证书集合,通常会包含依赖方已经的信任锚点(例如,根证书)。验证过程的一个关键步骤在于确定证书链中的一个或多个证书是否已被撤销。若是,则验证路径将失效。

互联网中实现证书撤销的两种方法:证书撤销列表(CRL)和在线证书状态协议(OCSP)[RFC2560]。

CRL:一个被签署的列表,它指定了一套证书发布者认为无效的证书。除了普通CRL外,还定义了一些特殊的CRL类型用于覆盖特殊领域的CRL。

OCSP:一个应用层的请求/应答协议,通常运行在HTTP协议之上。当用户试图访问一个服务器时,在线证书状态协议发送一个对于证书状态信息的请求,服务器回复一个"有效"、"过期"或"未知"的响应。

OCSP克服了CRL的缺陷:必须经常在客户端下载以确保列表的更新。

TCP/IP安全协议与分层

存在与OSI协议栈中各层次以及一些'中间'层的安全协议,如下:

层号     层名称       实例
7       应用层       DNSEC/DKM/EAP/Diameter/RADIUS/SSH/Kerberos/IPsec(IKE)
4       传输层       TLS/DTLS/PANA 
3       网络层       IPsec(ESP)
2       链路层       802.1X(EAPoL)/802.1AE(MACSec)/802.11i/WPA2/EAP

网络访问控制

网络访问控制(NAC)是指对于特定系统或用户而言用于授权或拒绝网络通信的方法。

由IEEE定义的802.1X基于端口的网络访问控制(PNAC)标准广泛用于TCP/IP网络,为企业局域网提供安全,其中包括有线和无线网络。PNAC的目的在于只有当系统或用户基于网络接入点完成认证后,才会为其提供网络访问服务。由于常与IETF标准的可扩展身份验证协议(EAP)配合使用[RFC3748],所以802.1X协议有时也称为局域网上的EAP协议(EAPoL)。2010年的版本[802.1X-2010]还包括了802.1AE(IEEE的局域网加密标准,称为MACSec)与802.1AR(面向安全设备表示的X.509证书),还包括了一个比较复杂的MACSec密钥协商协议MKA。

EAP可与多种链路层技术一同使用,并提供多种方法来实现身份验证、授权及计费(AAA)。然而EAP本身并不执行加密,所以它必须与其他一些加密功能矫情的协议一同才能保证安全。如下图是EAP的一个实例设置:

上图假设了一个包括有线和无线端点的企业网络,这个受保护的网络包括了AAA服务器、特殊虚拟局域网中的内网服务器以及一个不需要认证的虚拟局域网。认证者负责与未认证端点以及AAA服务器进行交互以确定是否给予每个端点访问受保护网络的权限。上图认证者能够以'直通模式'允运行,以帮助认证者免于执行大量的认证方法。

EAP数据包的格式非常简单,如图所示:

代码字段包含了6中EAP数据包类型之一:请求(1)、响应(2)、成功(3)、失败(4)、初始化(5)、结束(6)。

标识符字段包含了一个由发送者选择的序号,用于匹配请求与响应。

长度字段给出了EAP消息的字节数(含代码、标识符、长度)。

典型的EAP交互过程:

  1. 从认证者发送一个请求消息给端点;

  2. 端点以一条响应消息作为回应,两条消息使用的格式相同。

请求与响应消息的主要目的在于交换实现成功认证所需要的信息,如下图:

EAP消息承载着端点与认证者之间的认证材料。

EAP是一个支持自身的多路复用与多路分解的分层体系结构,从概念上讲,它包括四个层次:底层、EAP层、EAP端点/认证者层、EAP方法层。底层负责有序的传输EAP帧;EAP层实现可靠性和消除重复;EAP端点/认证者层负责实现端点与认证者协议的消息,基于对代码字段的多路分解实现;EAP方法层包含了所有用于认证的特殊方法,包含任何用于处理大消息的协议操作。

网络接入认证信息承载协议(PANA)作为EAP的下次,扮演着EAP信息承载者的角色,它使用UDP/IP协议(端口号716),因此能够用于多种类型的链路,并且不限于点对点的网络模型。

PANA的框架包含了三个主要的功能性实体,PANA客户端(PaC)、PANA认证代理(PAA)、PANA中继原件(PRE):

  PANA的用途通常包含认证服务器(AS)和执行点(EP),AS是一个通过访问协议访问的常规AAA服务器。

  PAA负责将认证材料从PaC传输至AS,并且在网络访问被批准或撤销时对EP进行配置。

  PaC与PAA之间的直接通信不能实现时,PRE可用于两者之间的中继通信。

PANA协议由一组请求/响应消息构成,包括一个有"属性-值"对组成的扩展集合。PANA会话包含4个节点:认证/授权、访问、重新认证、终止。重新认证实际上是访问阶段的一部分,所以重新认证后会话的生存期也得到相应的扩展。终止节点一般会以明确的方式进入,也会因为会话超时而进入。

PANA是一个弱传输协议,它按照"stop-and-wait"模式工作,没有使用自适应的重传计时器,不能够对数据包进行重新分组。当出现多个数据包丢失的情况时,它的重传计时器会以指数的方式进行回退。

IP安全(IPsec)

IPsec的操作可分为建立阶段和数据交换阶段。建立阶段负载交换密钥材料并建立安全管理(SA);数据交换阶段会使用不同类型的封装架构,称为认证头部(AH)与封装安全负载(ESP)。

一个完整的IPsec包含了SA建立协议、AH(可选)、ESP以及一些合适的加密套件、配置信息与设置工具。[RFC6071]总结了所有IPsec组件的发展过程与当前规范。

IPsec会有选择地针对某些数据包进行操作,这些操作基于管理员所设定的策略。所有的策略都包含在一个安全策略数据库(SPD)中,逻辑上与每一个IPsec的实现相伴。IPsec还需要两个额外的数据库,称为安全关联数据库(SAD)和端点认证数据包(PAD)。下图简单的描述了需要如何使用这些数据库及如何处理数据包:

SA

IPsec的第一步就是建立SA,SA是在两个通信方之间建立的单工(单向)认证关联。常见的情况是双方之间的双向通信,因此需要一对SA才能有效地使用IPsec,特殊协议Internet密钥交换(IKE)自动完成这项工作。IKE开始于一个简单的请求/响应消息对,该消息对包括一个建立以下参数的请求:加密请求、完整性保护算法、Diffie-Hellman组,以及根据任何输入的比特串随机生成输出的PRF(PRF用于生成会话密钥)。

IKE的前两次交换称为IKE_SA_INIT和IKE_AUTH,建立一个IKE_SA和CHILD_SA。随后出现两个交换,其中CREATE_CHILD_SA交换用于建立其他的CHILD_SA,INFORMATIONAL交换则用于初始化SA中的变化或收集SA的状态信息。IKE消息封装在UDP中通过端口500或4500发送,而IKE的接收者则应该准备接收来自任何端口的流量。

IKE消息格式如下:

SPI,安全参数索引,一个64位的号码,用于标识一个特定的IKE_SA,发起者和响应者都会有一个属于自己的SA,所以它们能提供正在使用的SPI,这一对SPI值能够与通信两端的IP地址结合起来用于形成一个有效的连接标识符。

下一个负载字段指出了后面负载的类型。

主要版本字和次要版本字段应分别设置为2和0,当无法维持版本直接的互操作性时,主要版本号就会被修改。

交换类型字段给出了消息的交换类型,包含:IKE_SA_INIT(34),IKE_AUTH(35),CREATE_CHILD_SA(36),INFORMATIONAL(37),IKE_SESSION_RESUME(38),其他数值被保留,240~255范围被留作私人用途。

标志位字段定义了一个3比特位的字段:I(发起者,第3位),V(版本,第4位),R(响应者,第5位)。I由原始发起者设置,接收者会在返回消息中将其清除;V指出一个版本号,高于发送者当前使用的协议的主要版本号;R指出当前消息是之前某一消息的响应,与其使用相同的消息标识符。

消息标识符字段是于TCP序列号类似的功能,标识包含该标识符的数据流的第一个字节。不同的是发起者消息标识符从0开始,而响应者从1开始。无论是在发送还是接收时,消息标识符都会被记录下,这样做可以帮助每一个通信端检测重放攻击。

长度字段统计了IKE消息头部和所有负载的合计大小。

IKEv2负载类型表,数值0表示没有下一个负载:

"通用"的IKEv2负载头部如下图所示:

通用的负载头部固定为32位,下一个负载与负载长度字段提供了一个大小可变的负载"链"(最多位65535字节,包括负载头部的4字节)。C位指出当前负载对于一个成功的IKE交换而言被认为是"关键"的。

IKE_SA_INIT与IKE_AUTH交换过程:

HDR IKE 头部(非有效载荷);SAi1/SAr1(SAi2/SAr2)分别表示发起者和响应者可支持的密码算法套件,数值表示阶段;KEi/KEr表示双方的 Diffie–Hellman密钥交换内容和一次性随机数。

CREATE_CHILD_SA交换用于创建或更新一个CHILD_SA,或用于更新一个IKE_SA。交换过程如下:

INFORMATIONAL交换用于传输状态与错误信息,通常使用N(通知)负载。交换过程如下:

AH

IP认证头部(AH)[RFC4302]是IPsec协议套件的可选部分,提供了一种源认证与保护IP数据报完整性的方法。

看下IPsec AH处理后的IP头部(IPsec头部):

IPsec AH处理后的隧道模式IP头部:

AH结构:

下一个头部字段指出下一个类型值。

负载长度字段指出AH的长度。

保留字段作为保留。

安全参数索引字段包含一个32位的位于接收者端的SA标识符,指出AH属于哪个SA,随着每一个SA数据包的发送而增1。

序列号字段,如果开启,则用于重放保护。

完整性校验值字段是可变的,且依赖于使用的密码套件,该字段在长度上保持为32比特的整数倍。

ESP

IPsec的封装安全负载(ESP)[RFC4303],也称作ESP(v3)(注意,其本身并不提供正式的版本号),提供了一个可选的组合,包括机密性、完整性、原始认证以及对IP数据报的反重放保护。

看下IPsec ESP处理后的IP头部(IPsec头部):

IPsec ESP处理后的隧道模式IP头部:

ESP结构:

安全参数索引字段包含一个32位的位于接收者端的SA标识符,指出ESP属于哪个SA,随着每一个SA数据包的发送而增1。

序列号字段,如果开启,则用于重放保护。

负载数据以32位(IPv6中64位)为边界终止,并且最后两个8位字段能够识别填充长度与下一个头部字段值,填充、填充长度、下一个头部字段共同构成了ESP尾部。

完整性校验值字段是一个长度可变的尾部,用于启用完整性支持以及满足完整性检验算法的需要。它会对ESP头部、负载以及ESP尾部进行计算。ICV的长度取决于所选择的特定完整性检验方法,因此它会在相关的SA建立之后才建立起来,并且要求SA在其生存期中不发生改变。

传输层安全(TLS和DTLS)

传输层安全(TLS)用于保证Web通信以及其他流行协议的安全,其面向数据报的版本成为数据报传输层安全(DTLS)。

TLS协议本身分为两层:记录层和上层。如图所示:

TLS是一个客户端/服务器协议,设计用于为两个应用程序的连接提供安全。记录协议提供分片、压缩、完整性保护及客户端与服务器之间所交换数据的加密服务。信息交换协议(即上层协议)负责建立身份、进行认证、提示警报、以及为用于每一条连接的记录协议提供唯一的密钥材料,其包含4个特殊的协议:握手协议、警告协议、密码变更协议、应用数据协议。

记录协议

记录协议使用一个可扩展的记录"内容类型"值集合来识别可多路复用的消息类型。

在任何给定的时间点时,记录协议有一个活跃的当前连接状态和一组被称为挂起连接状态的状态参数;每一个连接状态又进一步被划分为读状态和写状态;每个状态又指定一个压缩算法、加密算法和用于通信的MAC算法,同时还包括必需的密钥与参数。

TLS记录过程:

压缩算法可以为NULL压缩协议,即不提供任何压缩,且压缩算法应该是无