Skip to content

Latest commit

 

History

History
240 lines (150 loc) · 40.3 KB

第02章-基本安全概念.md

File metadata and controls

240 lines (150 loc) · 40.3 KB

基本安全概念

这一章主要介绍基本的安全概念和它们在TPM中的应用。因为从应用的角度来说,理解这些概念背后的数学原理并不重要,因此我们也不做过多介绍(事实上译者也是小白)。相反,我们会更多的讨论各种密码学算法的行为,从而帮助你理解TPM2.0规范是如何使用这些算法的。

安全专家可以忽略这一章。如果你已有零碎的相关知识,建议你浏览一遍从而让你恢复记忆或者理解TPM如何利用基本的密码学概念。如果你对密码学或者TPM一点概念都没有,这一章必读哦。

TPM2.0规范中使用的所有密码学算法都是基于公开标准的算法,并且这些算法都被广泛地评审过。从头设计一个定制化的具有相当密码学强度的算法是非常困难的。一个密码学算法只有在经过长时间的密码学分析之后才有可能被认定为是高强度的,同时只有满足一定规则要求的算法才会被TCG允许在TPM规范中使用。这一章将介绍三种类型的算法:用于完整性的哈希算法,用于保密性的对称加密算法,用于数字签名和密钥管理的非对称加密算法。具体来说,我们将讨论安全哈希算法,AES(Advanced Encryption Standard)以及两种非对称密码标准:RSA和椭圆曲线密码(ECC)。在介绍具体的算法之前,我们首先要知道它们分别用于防护什么。

我们以两种攻击类型的描述来开始本章:暴力攻击和密码分析。然后定义一些基础的概念:消息,秘密,完整性,认证和授权,同时附带两个高层的概念,防止重放攻击和不可抵赖性。最后,分别列出TPM使用的密码学算法。

首先,内容最多的一部分是通用的安全规则。因为这些规则贯穿于本书以及TPM的设计中,我们将详细描述这些规则在TPM2.0中的特定应用来加深理解。通常情况下,TPM以常用的方式使用密码学算法,如果有什么例外,我们将在这里解释。(以extend操作为例,它是一个通用的安全概念,TPM以一种全新的方式来使用它)

需要说明的是,TPM规范中做的每一件事情都是为了减少密码攻击的可能性。

密码攻击

密码学因阻止攻击者作恶而生。一个基于密码学的安全系统用于阻止心怀恶意的人盗取你的数据,冒充你,或者在你没有察觉的情况下修改你的文档。攻击者通常通过两种方式破坏密码设计的安全性:深入理解密码和协议背后的数学原理来寻找漏洞,或者暴力破解。

如果你使用经过完善审查的算法和协议,同时遵守它们的使用方式,你的设计在很大程度上不会遭受第一种类型的攻击。而暴力攻击不同,攻击者使用每一个可能的密钥,输入,或者口令试图猜测用于保护系统设计的秘密信息。

暴力破解

密码学家通常不会声明一件事情不可能发生。他们总是说这个事情“计算上不可行”,意思是说攻击一个密码需要不切实际的大量时间来尝试每一种可能的组合。以DES(Data Encryption Standard)为例,一共有2的56次方个可能的密钥。这个数目是72,057,594,037,927,936,哇哦。破解DES算法尽管看起来在计算上不可行,它最终还是在1998年被一台特别制作的机器破解(wiki)。

口令也经常被暴力破解。首先是尝试单词字典,然后是单词,数字甚至是特殊符号的组合。奇葩的是攻击者甚至可以使用Klingon和The Lord of the Rings书中的单词来破解,RainbowCrack就是一个为人熟知的暴力破解的例子,即使你的口令很长也无济于事。

如果一个密码算法的安全强度不依赖算法实现细节的保密,那就认为它是一个好的算法设计。当一个算法不能通过猜测它的密钥来破解时,它就是不可攻破的。防止暴力破解最主要的两种方式是:选择足够长的密钥使破解在计算上不可实现,或者想办法限制攻击者在一定时间内尝试的次数。

TCG假定所有它采用的算法都是经过良好设计的。这个假设不一定是绝对正确的,因为并不是每一种算法都是经过广泛的实际验证的(前文只是说,每一种算法都经过很详尽的算法分析)。当然TPM规范的算法灵活性也保证了如果将来的某一天TPM采用的一种算法被证明是不安全的,那也只是需要把这个算法从可允许使用的算法列表中删除,而不是重写规范。

密码算法本身的强度体现在它对数学原理层面攻击的免疫力,而一个算法的应用实现强度则和算法类型以及密钥大小的选择息息相关。

根据类型来计算算法强度

对称算法使用同一个密钥来做加解密操作,它是一种传统的加密方式。对于一个设计良好的对称密码算法来说,它的强度与所使用密钥的长度成指数关系。举例来说,如果一个密钥只有4比特长,那一共只有16种可能的密钥。一个暴力攻击者经过16次尝试后一定可以破解这个密钥。因为密钥的选择是一个随机的过程,通常来说平均需要尝试密钥空间大小一半的次数就可以找到正确的密钥,在这个例子中也就是平均尝试8次就可以破解。因为密码强度与密钥的比特位数成指数关系,我们通常使用密钥的比特位数来表达一个算法的强度。具体来说,对称密码算法的强度就是密钥的比特位数。在TPM规范中,对称密码算法经常使用的密钥长度是128,192,256比特。

安全哈希算法只能加密不能解密。这听起来好像没有什么用处,但是事实上它有很多种有意思的应用。哈希算法的一个重要特点是,无论输入的长度是多少,它总是产生相同长度的输出。更加有趣的是,不能解密意味着给你一个哈希算法的输出,你不能反推出它的输入是什么。这种算法的强度体现在以下两个方面:

  • 能够产生给定的哈希输出值之前尝试的次数。对于一个设计良好的哈希算法来说,这个次数值是该算法输出比特长度的指数(2^)
  • 当两个不同的输入产生相同输出的概率为50%之前需要尝试的次数。对于一个设计良好的哈希算法来说,这个次数值应该是算法输出长度一半的指数(2^).(具体的原因译者也不是很清楚其数学原理,看原文或者google一下birthday attack吧)

哈希算法的使用多种多样,但是因为密码学者通常有三类人-职场人士,专家,幻想狂,通常最后一种人的使用方式被认为是设计良好的使用方式,穷尽一切可以想到的方法来减小被攻击的可能性,你懂得。

非对称算法给人的第一感觉是很奇怪,它的加密和解密使用不同的算法,不同的密钥。不同的密钥-公钥和私钥,共同组成了非对称算法的密钥对儿。稍后我们将在本章介绍两种你需要关心的两种非对称算法:RSA(自行搜索)和椭圆曲线密码(ECC)。

对于非对称密码来说,很难通过其密钥长度来计算算法强度。如果是RSA算法,我们有相关的列表可供参考。这个表会列出2048位的RSA密钥强度与112位的对称密钥强度相当,3076位,15360位分别与128位,256位的强度相当等等诸如此类的关系。对于ECC来说,其强度与密钥长度是其一半的对称算法相当。例如256比特,384比特密钥强度分别与128位,192位的对称算法密钥强度相当。

如果攻击者因为密钥长度太长而无法实现暴力破解时,他们就可能尝试分析算法的数学原理来挖掘可能的漏洞,从而实现破解。

针对算法本身的攻击

密码算法的设计有一定程度的艺术性。算法背后的原理通常用于解决一类特定的问题,反过来其难度也受限于设计者当前的认知。事物总是在不断的发展变化,所以很难设计一种可以免受任何攻击的算法。

前文也有提到,针对SHA-1的攻击直接推动了TPM由1.2版本向2.0版本过渡。在通常情况下,暴力生日攻击破解SHA-1算法大概需要2的80次方的尝试。针对算法数学原理的攻击可以将所需的攻击次数降低到2的63次方,就是说将SHA-1的80比特位的强度降低到63位。SHA-1算法贯穿TPM1.2的设计,随着56比特位强度的DES加密算法在1998年被破解,工业界也认识到可以被降低到63位强度的SHA-1算法是不够的。正因为如此,TPM2.0的设计消除了对SHA-1的依赖。正如前文所述,TPM2.0被设计成算法可以灵活配置,并且不需要修改规范。

总结来看,为了保持安全性,密码算法必须不能有以下两种漏洞:

  • 算法本身的强度不够,可以通过选择被广泛审查和应用的算法标准来解决。
  • 不能抵御暴力攻击,主要是通过选择更长的密钥来解决。目前通常情况下128位的对称算法被认为是安全的,但是一些研究人员坚持192位才足够安全。

到现在为止你已经看到了将要应对的攻击,接下来我们将介绍基本的密码学概念。首先,介绍一些基础定义。

安全的定义

以下涉及的一些定义对于理解TPM的架构和密码学概念非常重要。人们常常将安全仅仅视为保密,也就是说如果攻击者不能拿到你的私密信息就是安全的,这显然是不正确的。尽管保密非常重要,但是安全远远不止于保密。通过一个实际的例子就能理解为什么。因为TPM设计的一个重要驱动力来自于电子商务,所以下面我们将引出一个电子商务的例子来详细说明。

在电子商务交易中,消费者会向商家发送一个电子订单。消费者和商家都希望保证交易过程中的私密信息(信用卡号等等)是安全的。但同时商家也希望保证消费者不是恶意的攻击者,消费者也希望只有真正的商家能收到自己的订单;同时还要求电子订单不能再传输过程中被修改(比如修改订单中商品的数量),并且同一个订单不能被多次发送。另外,商家也可能需要对消费者的消费行为进行限制,比如订单消费的总量等。密码学和安全传输协议试图努力解决所有以上的电子商务问题。

基于上面的例子,我们引出一些常用的安全概念,并解释他们分别应用于安全的方方面面。

  • 消息:交易或者通信双方产生的一个数据流。
  • 保密:一种防止未授权的观察者辨识消息内容的方法。
  • 共享秘密:双方都知道的一个值。这个秘密可以是口令或者是加密密钥。
  • 完整性:用于指示消息在存储或者传输中没有被篡改。
  • 认证:一种可以证明一个消息只能来自一个特定的消息创建者的方法,因此接受者可以通过这个方法认定消息的创建者发送了这个消息。
  • 授权:一个可以表明用户具有某种操作权限的证明。
  • 防止重放:一种防止攻击者重复利用有效信息的方法。
  • 不可抵赖:一种可以阻止一个消息的发送者否认发送了该消息的方法。

现在我们来说明一下这些概念是怎样在电子交易中被应用的。消息就是订单的内容,它包含了商品的数量和顾客的机密信息,比如信用卡卡号。完整性能够保证订单作为消息在传输过程中没有被篡改,比如商品数量由3被修改成300。商家通过对订单发送者进行身份认证来确认订单确实来自一个真是顾客而不是攻击者。同时商家可以基于公司利益的考虑决定顾客是否有订单相关商品的购买权限。如果攻击者多次将顾客的订单发送给商家,就会造成双方的经济损失。防止重放的方法可以阻止攻击者重复发送订单。不可抵赖的方法可以保证顾客在确认订单以后就不能否认自己曾经下过单这个事实。

安全系统的设计者为了满足上述的安全特性需求制定了密码学工具箱,并仔细分析改进和促使它们标准化。这其中有一些由基础的数学运算构成,比如说SHA-256哈希运算和RSA加解密运算。而另外一些则是在前者的基础上构建而成,比如数字签名就应用了RSA算法。接下来我们将逐一介绍。

密码家族

首先要声明的是这一节没有数学相关的内容。我们也不会描述素数算法和椭圆曲线。但是理解一些密码学的基本运算以及这些运算和我们已经了解到的安全概念的关系是非常重要的。

概括来说,哈希算法用于提供完整性。同时哈希可以和一个共享秘密组合成HMAC来实现认证。HMAC反过来又是密码学凭据和密钥生成器的基础。对称加密中会使用共享的秘密作为加解密密钥。随机值则用于防止重放。非对称密钥常作为签名密钥来保证不可抵赖性。TPM也会使用非对称密钥来加密一些通信协议。接下来我们将逐一介绍。

哈希(摘要)

大多数的计算机专业学生对哈希都很熟悉;简单的哈希经常用于加速搜索,更加高级一点的哈希用于检测数据错误。但是密码学中的哈希因为要用于防止攻击者破坏系统,所以密码学家会给这种哈希算法增加一些非常特殊的属性。

密码学哈希和其他哈希算法一样,它能够接受任意长度的消息,然后将消息压缩转化成固定长度的哈希值。比如说,SHA-256算法的输出是固定的256比特或者说32字节。基于安全性的考量,这种哈希算法必须具备以下重要的属性:

  • 在给定一个消息的情况下,不可能找到与之哈希值相同的不同消息。
  • 两个不同的消息产生相同哈希值是不可能的。
  • 不可能由哈希值反推出消息

即使一个消息仅有非常细微的变化,经过哈希处理之后的结果也会千差万别。下面是使用SHA-1算法对字符串做哈希的例子,“Hello”的哈希是:

fedd18797811a4af659678ea5db618f8dc91480b

在将字母H由大写改为小写,“hello”的哈希值是:

aa5916ae7fd159a18b1b72ea905c757207e26689

TPM2.0规范允许使用多种不同的哈希算法,这其中包括SHA-1,SHA-256,SHA-384。 通常情况下,一个TPM硬件实现的算法是规范中所有算法的一个子集。困扰规范开发者很长时间的一个重要问题是,怎样在规范中集成多种哈希算法以防一种算法在以后失效。这件事情听起来简单做起来难,需要特别小心。因为哈希算法经常用来做消息的完整性报告,如果哈希算法是不可信的,那么完整性报告的可信性也就无从谈起了。最终的设计在很多地方使用了算法标签来指示相关操作使用什么哈希算法。

前文已经提到,安全哈希算法是TPM中很多其他操作的基础,比如哈希扩展操作,HMAC,凭据,基于非对称密钥的数字签名,密钥生成器等。

哈希扩展(HashExtend)

虽然扩展并不是密码学中的概念,但是TPM中扩展的应用贯穿始终。一个扩展操作包含以下步骤:

  1. 初始时,有一个哈希值A。
  2. 连接哈希值A和一个消息B,组成另外一个消息A||B.
  3. 对A||B做哈希。
  4. 用A||B的哈希值替代原有的哈希值A。

整个过程可以被总结描述为:A<-hash(original A || B) 举例来说,使用SHA-1将‘abc’扩展到一个全部是0的原始值中,得到的结果是:

ccd5bd41458de644ac34a2478b58ff819bef5acf

在一系列的扩展操作之后,最终的哈希值能够有效地“记录”这些操作的历史(但并不是像一个详细记录每一个操作的列表那样)。因哈希算法的特殊属性,我们不可能反推历史值是多少。这样一来一旦完成扩展操作,就杜绝了修改之前的操作记录,销毁历史等情况的产生。另外,同样因为哈希本身的属性,不管我们对一个值做多少次哈希扩展,使用SHA-256算法得到结果永远都是32字节长。这个固定长度的特点,可以帮助内存受限的TPM实现理论上次数不限的历史纪录功能。

具体来说,扩展操作用于更新平台配置寄存器(PlatformConfigurationRegister(PCR))的值。一个PCR就是TPM中一个用于存储哈希值的寄存器或者说内存区域。其中存储的哈希值用于表征平台的状态。假设在某个时刻一个PCR的值表明平台现在处于不可信的状态,这个不可信的状态可能是攻击者修改了平台的固件所致。因为这个不可信的状态可能被系统发现并阻止进一步操作,所以攻击者可能会试图向当前的PCR扩展一个消息使PCR的结果变得可信。此时安全哈希算法的特殊属性保证了攻击者不可能实现这种操作。

扩展操作还可以被应用于审计日志。审计日志记录了一系列TPM的命令及响应数据。这个功能将会在扩展的授权(ExtendedAuthorizaiton)那一章详细介绍。

在TPM1.1和1.2中,基于哈希的HMAC也应用于简单的授权操作。

基于哈希的消息认证码(HashedMessageAuthenticationCode)

一个HMAC就是包含密钥的哈希。意思是说,在做哈希操作的同时混入HMAC密钥。因此只有拥有HMAC密钥才能得到正确的HMAC值。HMAC在消息中的应用就是“HMACing”这个消息。

在TPM 1.2中,HMAC被广泛用于证明一个用户拥有一个TPM资源实体的使用权限。TPM2.0也支持这种授权方式。需要说明的是,HMAC密钥是TPM设备和用户都知道的共享秘密。举例来说,一个TPM对象(比如签名密钥)的使用权限数据可能与一个HMAC密钥相关,这个密钥是TPM和授权用户都知道的。用户在使用这个TPM对象之前需要首先构造一个命令消息,然后由对象的权限信息派生出HMAC密钥(这就是前面描述的相关的意义所在),接着使用HMAC密钥对命令消息做HMAC操作。当TPM收到命令消息和前述的HMAC操作结果之后,使用同样的方法产生HMAC结果。如果两个HMAC值相同就说明命令没有在传输过程中被修改,即命令消息具备完整性。并且命令的发送者确实知道与这个TPM对象关联的HMAC密钥,这意味者命令发送者是经过授权的。这就是一个基于HMAC的授权过程。

有时候TPM内部的一些数据需要保存到TPM之外的存储中,HMAC来保证整个过程中数据的完整性。也就是说HMAC可以用于判定存放在TPM之外的数据有没有被恶意修改。在这种情况下,只有TPM知道HMAC密钥,密钥不是前面所说的共享秘密。具体的操作上来说,TPM在将一个数据发送到TPM之外时同时包含这个数据的HMAC值,当数据再次被加载到TPM内部时,数据的HMAC会被重新计算并与之前的计算值比较,从而确定数据有没有被修改过。本质上来说,这种情况下的HMAC密钥也可以理解为一种共享秘密,只不过共享秘密的双方是不同时刻的TPM,不同时刻是指数据在保存到TPM之外时和数据重新被加载到TPM内部时。这种技术在TPM中的一个具体应用叫做认证凭据。TPM通过这个凭据来让自己相信数据没有被修改过。

除此之外,HMAC还被应用于产生密钥,这就是下面要介绍的密钥生成函数。

密钥生成函数(KeyDerivationFunction)

TPM厂商在交付TPM时可能会附带不同类型和长度的密钥的证书(证书由公钥等信息组成,google一下,你就知道)。但是因为TPM的存储空间限制,用户密钥证书的空间也不大。更糟糕的是TPM中的不同协议需要不同的秘密信息,比如说,对称加密和HMAC就使用不同的密钥,而这些都需要存储或者说需要一种存在形式供TPM使用。为了降低成本,TPM被设计成可以通过一个秘密信息生成不同的密钥。这个秘密信息称作种子,而算法通过密钥生成函数和这个种子来生成相对应的密钥。TPM就是通过这样的方式来生成对称和非对称密钥的。

实际上,TPM根据NIST的800-108规范将HMAC方法作为密钥生成函数。具体的实现上来说,就是用种子(seed)作为HMAC密钥对一些数据(具体算法相关)做HMAC操作,其结果就是密钥。而被HMAC方法操作的数据就是用于描述具体算法的字节流。这样一来就保证了可以利用同一个种子在不同的应用中使用不同的密钥,不同应用使用不同密钥是密码学的基本规则之一。另外在生成密钥的时候也会包含其他一些唯一性的数据。这用来保证通过这种方法生成的密钥是唯一的独立的。

认证或者授权凭据(Ticket)

凭据就是包含一些源数据以及这些源数据HMAC值的数据。正如前文所述,凭据可以用来验证数据在经历一定的时空变化之后是否还完整。另外,HMAC还可以避免重复的正确操作。为了解释这一点我们首先要做以下说明。在实际应用中,用于生成凭据的消息通常是原始数据的哈希值,因为原始数据一般都很大。另外,TPM常常分解密码学操作,然后按照一定的时间顺序操作。同时我们再次声明,此时的HMAC密钥只有TPM自己知道。

那TPM到底怎么做到防止重复操作呢?让我们举例来说吧。TPM经常会先对一个消息做哈希,然后对消息的哈希进行数字签名操作。需要说明的是很有可能这两次操作的中间间隔了很长时间(这要看具体的应用场景)。这时候TPM会生成一个凭据,这个凭据可以标识这样一个事实:我计算了这个哈希,并且这个哈希就是将来我要签名的哈希。在后续进行签名操作之前,TPM会首先验证这个凭据来保证数据的真实性和完整性,然后直接对哈希值进行签名,而不是对数据做哈希。读者可能会有疑问,还是没有看出来到底怎么避免重复操作。假设数据在第一次被加载到TPM中做了一些操作,一段时间后后会有一个签名的操作。如果源数据很大,TPM资源的限制导致它不能在TPM中长时间存在,因此对同一数据的两次操作之间数据可能会被“踢出”TPM,如果没有凭据这个技术,后续做签名操作时就需要重新加载数据。而加载数据又是一个很耗时的操作。所以凭据的这个应用可以大大提高TPM的操作效率。

数据在进出TPM的过程中,HMAC保证了数据的完整性。虽然完整性保证了,但如果数据是以明文的方式存储在TPM之外的地方还是会有问题。原因很简单,如果一个坏人想用你的身份证干坏事,他不需要冒风险破解公安部的数据库修改你的身份证号,他只需要把他看到的身份证号卖给其他人就可以。同样的道理,一些信息只要被其他人看到了就已经不安全了。这个时候常常需要对称加密密钥对原始数据进行加密以后再送到TPM之外。

对称加密密钥

对称加密密钥是一种应用于对称加密算法的密钥。对称加密算法使用相同的密钥做加解密操作。HMAC操作也是一样,但是它们操作的对象不同,HMAC操作对象是数据的哈希,对称加密算法是数据本身。这一点需要注意。

AES是一种典型的对称加密算法。同时TPM规范也支持其他类似的算法,比如Camellia和SM4(SM4是中国的算法),但是因为它们的功能和操作方式都大同小异,所以这本书仅仅涉及AES。对称加密算法在TPM中有以下三种不同的应用:

  • 保证TPM数据的机密性。此时对称密钥不会被存储到TPM之外,所以只有TPM可以创建和访问它们。当一种密钥因为存储空间的原因需要被存储到TPM之外时,它首先会被只有TPM可以访问的对称密钥加密。
  • 加密进出TPM的通信数据。此时对称密钥由消息发送者和TPM都知道秘密信息派生而来。通信过程中的数据会被这个密钥加密。
  • 把TPM当作一个对称加解密协处理器。因为TPM完全具备对称加解密的功能,这是完全可行的。你可以将一个对称密钥导入TPM,然后让TPM使用这个密钥来对数据加密。因为TPM的运算速度很慢,所以单纯的加解密功能通常用于少量数据加密。但是这个功能可以避免软件工程师使用密码运算函数库。如果加解密功能在TPM中是非必需的功能,TPM厂商倾向于不加入这个功能。因为在硬件中实现加解密功能常常会遇到商业授权方面的限制。

对称加密的应用不但需要选择具体的算法实现和对应的密钥,还需要选择加密的模式。不同的协议会应用不同的模式。下面介绍对称密钥的模式。

对称密钥的模式

典型的对称加解密算法通常用于对成块的大量数据进行加密。当数据以成块的模式被加密时,需要解决以下两个问题:

  • 如果数据块仅仅使用密钥来加密,这叫做ECB模式。因为使用这种模式时,相同的数据快产生的结果总是一样的。当一个位图以ECB的模式被加密时最终的结果是颜色变化(wiki)。这对于大量的数据没有作用,因为数据量变大以后总会出现相同的数据内容,所以最终的密文会有一定程度的体现,这是不安全的(TODO:这一块后续要做详细的解释,或者建议读者理解以下密码的发展历史)。为了解决这个问题TPM还支持其他的模式:CBC,CFB,OFB,CTR。所有这些模式能确保数据块不止一次被操作,所以即使大量的数据快中有相同的内容,最终的密文也不会体现出来。
  • 有一些模式要求输出必须是算法要求的成块大小,CBC就是这样。如果输入的数据大小与块大小不是整数比例关系,算法将会填充原有的数据块来满足要求。所以这就造成了输出数据大小比输入数据大的情况。对于有些应用来说这不是问题,但是不适合一些明确要求输入输出大小必须一致的应用,比如TPM命令数据流的加密。对于后一种情况,可以使用CFB或者CTR模式。CFB模式下,对称密钥会首先作用于一个初始向量(IV),然后把这个结果作为初始化向量作用于下一个数据块。在CTR模式下,对称密钥用于加密一个计数器的值。这两种模式都包含将输入数据进行异或的操作用于产生输出。有多少输入就操作多少,不会额外增加,所以这两种模式的输入输出的大小是一致的。

CFB和CTR(或者说是XOR操作)都有一个特点,那就是翻转密文数据流中的一个位置,那这个翻转会体现在解密明文的对应位置上。所以攻击者或许看不到原文的具体内容是什么,但是却可以很容易破坏明文。对于CBC模式来说,密文一个比特的变化可能会引起明文多个地方的变化,完全有可能使解密后的原文没有意义。

这就引出一个非常重要但常常被忽略的问题。加密仅仅提供保密性保护,但是不能提供完整性和认证功能。为了实现后者,TPM会对加密后的数据做HMAC操作而不是依赖加密后的数据看起来是不是对的。因此在实际应用中,对数据的解密总是在验证HMAC之前。

另外,机密并不能证明消息是最近产生的,举例来说有可能是很久之前的一次相同的操作中产生的(回忆以下前面介绍的防止重放)。这时候就需要nonce了

Nonce

一个Nonce就是只能在密码学操作中使用一次的随机数。它可以用来阻止重放攻击。为了保证消息不被有效地重复使用,消息的接受者会产生一个Nonce发送给消息发送者。发送者将Nonce包含在消息中。因为消息发送者不能实现预测接收者如何选择Nonce,所以发送者不能事先准备好一个有效的消息。需要注意的是,Nonce并不是简单地被包含在原有的消息中。当用户向TPM发送命令并接收到响应后,Nonce同时也结合HMAC向用户证明用户接收的结果确实来自于真实的TPM。

在典型的TPM应用中,nonce会被包含在HMAC的计算中。当消息涉及的操作完成以后,TPM会改变之前发送给命令调用者的Nonce值。如果调用者想通过使用原来的nonce完成消息重放时,TPM再次验证HMAC时就会失败。刚刚我们也说了,TPM一旦完成这个消息的操作就会把Nonce改掉。事实上TPM应该是完全“忘记”这个消息的nonce值,所以后面再次验证HMAC的时候就不可能成功了。

对于许多应用来说,一个nonce可以是一个逐渐递增的数,并且要足够大从而不至于产生溢出。但是这种方式需要TPM记住上一次nonce的值,很不方便。TPM的做法是充分利用其内部的随机数生成器。总结来说,TPM使用随机数作为Nonce,并且nonce的值足够大,不可能出现重复。

非对称密钥

非对称密钥主要被非对称算法用于数字身份和密钥管理。非对称密钥有两部分组成,只有一方知道的私钥和可以对所有人公开的公钥。非对称密钥应用了数学中的单向函数。这种函数可以通过私钥很容易地计算公钥,但是通过公钥推算私钥在计算上是不可能的。

通常私钥的拥有者可以用私钥对数据进行加密(假设私钥够长即强度够高),每一个拥有公钥的人都可以解密数据。又因为在设计上只有拥有私钥的人能访问私钥,所以这同时也能证明这个加密数据一定来自于公钥对应的私钥的拥有者。

如果有人(A)想给另外一个人(B)发送数据,并且希望这个数据只能由A之外的B看到。A可以使用B的公钥来加密数据,B通过私钥解密数据,这样就可以达到目的(当然实际操作中是有很多问题的)。所使用算法不同具体的操作方式也不一样,但是后面的介绍我们仍然不会涉及具体的数学细节。

RSA非对称密钥算法

RSA是广为人知(至少是计算机领域)的一种非对称加密算法。它使用一种能将大数转换成大素数的函数作为单向函数(这里的大就理解为位数很长很长的数,通常编码实现上利用一个大的数组来存储)。对于RSA来说,一个消息分别经过RSA的公钥和私钥作用之后,会返回成原来的样子,并且与两个密钥作用的顺序无关。

这样一来,RSA就可以被用于加解密和数字签名。在加解密应用中,公钥加密数据,私钥解密。在数字签名应用时则相反,私钥用于签名,公钥用于验签。我们将分别介绍其中的细节。

RSA用于密钥加密

就像本节开始描述的那样,为了使用非对称密钥做加密操作,你首先要得到对方的公钥。这并不难,因为公钥本身就是对所有人公开的。私钥的拥有者,也就是加密消息的接收者使用私钥解密数据。这个过程对于其他人来说是保密的,因为私钥只有消息的接收者有。

在实际应用中,非对称密钥不是直接加密原始数据。事实上可以加密的数据的大小是受非对称密钥大小的限制的。如果将数据分开并分别进行加密也是不切实际的,因为非对称加密算法通常很慢。

正如我们之前在介绍算法灵活性时提到的,一种通用的模式是用非对称算法加密对称密钥,用对称密钥加密数据。然后将加密的对称密钥和加密数据发送给接受者。接收者首先使用自己的私钥解密对称密钥,然后用对称密钥解密数据。

RSA用于数字签名

数字签名和HMAC很像,但是它具有额外的特性。签名者用私钥对数据进行加密操作就得到一个数字签名。验签就是用公钥解密签名数据。

数字签名可以保证消息的完整性和真实性。前文我们已经介绍过,HMAC也有这样的功能。但是基于非对称算法的数字签名有更多的特性,这主要体现在以下两个方面:

  • 因为验证签名会使用对所有人都公开的公钥,所以一个签名可以被多方验证。而HMAC不同,因为只有拥有HMAC密钥的人可以验证。应用场景上会更灵活广泛。
  • 因为理论上签名只能由拥有私钥的人来生成。当消息接收者可以使用某一个公钥成功验证一个签名时,第三方就会认定只有相应私钥的拥有者可以产生签名(不可抵赖)。但是HMAC就不能做到这一点,因为HMAC时双方都知道一个秘密,接收者完全可以自己生成一个签名,然后说是对方的签名。

与非对称密钥用于加密一样,数字签名通常也因为密钥大小的限制不直接操作原始消息。

常用的模式是,签名者先对消息哈希操作,从而得到消息的摘要,然后对摘要签名。接收者在验证签名的时候,会用公钥解密出消息的摘要,然后使用与签名者相同的哈希算法对消息再做一次摘要,然后对比两个摘要。这种签名验签之所以有效,是因为安全哈希算法所特有的属性,攻击者不能构造一个具有和原消息相同摘要的不同消息。

当然了,RSA并不是唯一的非对称算法。最近的TPM规范中也加入了现在越来越流行的椭圆曲线(ECC)算法。

ECC非对称密钥算法

ECC是另外一种密码学中应用的非对称数学方法。ECC与容易让人理解的RSA不同,它使用了一种基于有限域椭圆曲线的数学概念。我们在这里仅仅是介绍它的应用,不涉及相关数学。与所有其他的非对称算法一样,ECC算法的密钥也包括一个公钥和一个私钥。公私密钥在应用上与RSA相同,这里不再赘述。

在相同的密钥强度下,ECC的密钥长度要远远小于RSA的密钥长度。之前我们也讨论过,ECC密钥的强度是其密钥比特长度的一半。也就是说256比特的ECC密钥的强度是128比特。与之强度相当的RSA密钥的长度可达3076比特。较小的密钥长度在一定程度上可以加快运算(当然还是比RSA慢)。对于加解密来说,ECC应用于ECDH,ECDH用于密钥交换。对于数字签名来说,ECDSA是对应的方法。

ECDH用于密钥交换

当ECC用于数据加解密时,我们实际上使用的是一种叫ECDH的算法。ECC和RSA在数据加解密上最主要的不同是,ECDH使用两个步骤而RSA只有一个步骤。具体到TPM的应用中,RSA加密就是用TPM的RSA公钥加密数据,而使用基于TPM的ECDH密钥操作时需要下面两个步骤:用软件的方法生成另外一个ECDH密钥,然后用这个新生成的ECDH私钥和TPM的ECDH公钥产生一个临时的随机数,然后在用KDF把这个随机数转变成一个对称密钥。简单来说,RSA直接加密对称密钥,而ECC直接生成对称密钥。

为了恢复ECDH相关的对称密钥,TPM使用前面提到的软件生成的ECDH公钥和TPM自己的ECDH私钥重新生成随机数。从而可以使用相同的方法通过KDF生成对称密钥。

ECDSA用于数字签名

ECDSA是通过ECC算法生成签名的算法。它用私钥签名公钥验签,这一点和RSA相同。两者在应用上的主要不同(数学原理除外)跟密钥的长度相关,因为ECC的密钥的长度要远远小于RSA的密钥长度,你必须确保要签名的消息摘要不能太长。(虽然RSA也要注意这一点,但是通常RSA的密钥长度都大于1024比特位,而现有的哈希算法中最长的输出结果是512位,所以这个对于RSA来说不用太担心)

对于RSA来说,通常情况下可以签名任何现有哈希算法的输出结果。但是对于ECDSA来说一般是使用相互匹配的哈希算法,比如SHA-256对应ECC-256,SHA-384对应ECC-384。如果你使用一个ECC-384密钥签名SHA-512的结果,ECDSA最终只会使用其中384比特位的哈希值。当然使用较长的密钥签名相对较短的哈希是没有任何问题的。比如ECC-384可以签名SHA-384,SHA-256或者SHA-1(160比特位)的结果。

所有的数字签名协议都会面临这样一个问题,接收者必须确认他们使用的公钥真的是来自于想签名的人。换句话说,怎么防止攻击者自己生成一对儿公私密钥,然后给接收者发送公钥和一个对应私钥的签名,签名的数据中包含以其他人身份的非法操作(这种情况下签名可以通过,但签名的数据是恶意的)。是时候让公钥证书登场了。

公钥证书

证书是非对称密钥协议的一部分,它主要解决下面的问题:怎么才能相信一个公钥?毕竟从功能上来说,如果你都不知道发给你公钥的人的真实身份,那它仅仅就是用来做了一个非对称的解密操作而已,并不能称得上是验证签名(你都不确定签名的人是谁)。同样的道理,用一个来源未知的公钥加密数据也是不安全的没有任何保密性可言的。万一公钥来自一个攻击者呢?TPM也有类似的问题,因此TPM需要有一种机制证明给公钥使用者这个密钥确实是来自正在与之交互的真实的TPM。

这个问题的解决办法就是数字证书。一个证书主要包括一个被认证过的公钥和密钥对儿相关的属性。 这个证书本身会被一个证书认证机构的私钥签名。一个证书认证机构的公钥也可能被另外一个证书认证机构签名过,从而组成一个证书组织架构(又叫作证书链)。最终这样的证书链会停在一个根证书的地方。根证书中包含的公钥是不需要被认证的,换句话说是被证书链的验证者无条件相信的。

X.509标准规定了一种普遍应用的证书格式。然而对于一个存储资源受限的TPM来说,它根本不会创建任何X.509证书。TCG的基础设施组确实采用了X.509证书格式,而TPM也确实会存储这样的证书。但是TPM的证书存储仅仅是用于部署方便并没有任何安全目的。

在TPM的范畴内,有如下几种认证过程:

  • TPM厂商和平台厂商可能会在交付用户时提供他们的背书密钥(EndorsementKey),这些密钥(公钥)就是对应的证书。其中,TPM厂商的证书用于证明:厂商的背书密钥存在于一个确实由这个厂商生产的真实TPM中。平台厂商的证书则用于证明:平台的背书密钥确实存在于平台上的TPM中,并且平台支持相关TPM功能。这两种证书的格式就是X.509格式,因为这个格式被广泛使用。
  • 如果一个TPM密钥及其证书被描述成一个签名密钥。那么这个密钥可以被用于认证其他的密钥确实存在于TPM中并且具备一定的属性。TPM2.0有相关的命令来创建证书,但是因为X.509格式对于资源受限的TPM来说太复杂了,TPM使用一种自定义的证书格式。

本质上说,数字证书依赖于证书认证机构的完整真实性。证书认证机构是一个被证书创建者和使用者信任的中立机构。它的功能与管理资金流动和资产交易的契约机构类似。所以如果证书管理机构是值得信任的,你好我好大家好,如果不是,说什么都白搭。(这听起来还是有些无奈啊)

当TPM厂商位TPM生成证书时,它们会为到底应该使用什么样的算法而为难。因为厂商也不知道最终的用户到底想用哪一种算法,RSA-2048,ECC-256,ECC-384,或者是其他什么算法,这都有可能。生成证书过程中要用到的哈希算法和对称算法的选择也是类似。之前也已经提到了,TPM为了解决这个问题,增加了可以通过KDF产生很多密钥的方法。后续的(密钥)组织架构章节我们将会看到,TPM怎样做到在不耗尽存储空间的情况下支持不同类型的证书的。

小结

这一章我们通过一个应用样例来了解主要的安全概念,这些概念在书中后续的章节中用于解释TPM设计实现及其应用。TPM设计的主要原动力来自于电子商务,说来也并不奇怪,因为TPM的设计离不开具体使用用例的推动。接下来我们又介绍了密码学需要保护的攻击类型,然后我们了解了为什么需要选择被国际上广泛审查和应用的算法以及相应密钥强度的选择。同时复习了保密性,完整性,电子身份,不可抵赖的概念,以及它们如何与相应的算法联系起来:比如对称,非对称,哈希,HMAC。最后,我们认识了最新的TPM规范中全新的密码算法应用技术如哈希扩展,凭据,和证书。现在我们具备足够的知识来理解所有TPM应用案例。