用于计算机装置验证的系统和方法

文档序号:6574618阅读:531来源:国知局
专利名称:用于计算机装置验证的系统和方法
技术领域
本发明通常涉及计算机系统和软件方法,更具体地说,涉及用于计算机装置验证的系统和方法。
背景个人计算设备已成为我们生活中越来越重要的一部分,而且当这些设备与因特网相互连接时,安全地验证交易处理中所涉及的使用这些设备的实体就变得日益重要。
在一个操作系统的受保护的子域中执行特许操作的安全内核的观念在对计算机安全中是一个很陈旧的观念。然而,在现代商业操作系统的发展过程中,象在各种版本的Microsoft Windows、UNIX、以及小型设备的嵌入操作系统中反映出来的那样,传统的安全边界以及操作系统的响应度不是变得很模糊、被取代,就是安全漏洞层出不穷。在这种情况下,操作系统变得太大,致使不可能有能力来保证或用任何综合的手段分析该系统。即使在原则上可能有这样一种保证过程,但是实际上在这些系统期望的使用期内,看起来是不可能实现的。
一些系统已采用具有物理上或结构上分离的CPU来容纳安全关键数据和在更大的系统中执行安全关键功能。一个例子就是基于验证装置的智能卡。智能卡装置提供一个对一个或多个嵌入的加密密钥具有单一存取的分离的操作环境。它可连接到一个传统的计算机用嵌入的密钥来执行数字签名、用户验证、及由计算机启动的事务处理。同时它很小和简单,足以在一个相对全面的过程中分析它的安全特性。然而,智能卡和其它附加设备的引入对该环境来说增加了费用和复杂性,它通常要求用户和系统管理者安装卡阅读器,而且要求智能卡分配给这些机器的用户。另一个例子是在系统中使用一个具有用于存储密钥的本地专用存储的从属加密处理器。其功能类似于常插的智能卡的功能。
这些附加硬件的系统的另一个限制是该附加的CPU并不具备自己的输入和输出装置。对这些装置来说用户I/O系统进一步增加了费用和复杂性,而且通常在功能上和方便上很受限制。例如,完全依赖于所连接的计算机来告诉它对什么签名以及用嵌入的密钥来处理的一个具有一个CPU的加密附加装置,对在所连接的计算机上进行的删除该设备的某些保存值的安全威胁来说是很脆弱的。由于这些分离装置的隔离,对该装置来说,一般很困难或是不可能保证由主机正向其显示的交易处理是真实的。因此,在某些方面,该系统还得最终依赖于主机操作系统和应用程序的完善。
为了装置应用程序软件的网络验证的目的,本发明的一个目的是为装置提供一个强大的加密身份。本发明的另一个目的是用对系统来说最少的附加硬件来提供高保证。本发明的另一个目的是提供一个系统,允许只要求在商品类商业个人电脑中使用的硬件来完成计算机装置验证。
本发明的另一个目的是提供一个小的安全内核,其中该内核在从应用程序和操作系统分离的域中操作,在安全内核的实现中易于过程分析和建立信任的过程。本发明的另一个目的是允许安全内核访问操作系统(OS)的存储器和应用程序,以便建立需要安全内核函数的程序的可靠性和完整性。
发明概述为实现上述和其它的目的,本发明包括为计算机设备管理机构提供的系统和方法。本发明提供了一个小型的安全内核,便于在内核的实现中分析和建立信任的过程,同时消除了上述的附加硬件方法的限制。理论上来说,安全内核在从运行在主机上的应用程序和操作系统分离的一个域中运行,并访问操作系统OS和应用程序的存储器。本发明通过在传统的现有操作系统的边界内创建一个小型的内部安全内核提供了这样一个安全结构,它能为OS和应用程序执行安全操作并验证其完整性。
本发明的密钥方面包括(1)含有一个保密主密钥的OAR锁定(OAR-locked)的非易失性存储器(NVM),在启动时能移动进入到系统管理模式(SMM),然后禁止OAR锁定(OAR-locked)的非易失性存储器;(2)容器将一个设备密钥赋给专用的应用程序,以及解决保密/用户可控性问题;以及(3)抽查被称为“忙碌”的调用应用程序的完整性。
设备密钥用于执行设备管理机构来补充用户验证,保护仅仅分配给特定设备的内容,以及例如用本地存储的和/或远程得到的凭证(或共用的凭证)启用一张虚拟的智能卡。该密钥容器用于增强系统关键密钥的保护,例如代替缺省的保密机API容器。
用于使用和保护访问一个主加密密钥的一个典型系统包括非易失性存储器;一个系统初始化过程,在系统初始化过程中从非易失性存储器读取主密钥,将一个来源于主密钥的灵敏值写入一个隐蔽的存储单元,禁止任何运行在系统中的程序访问非易失性存储器,直到下一次开始系统初始化过程为止;用于禁止在系统的正常操作模式中运行的任何程序访问隐蔽的存储单元的装置;以及用于允许在系统的一个受限的操作模式中运行的一段程序访问隐蔽的存储单元的装置。
在存储器中隐藏一个主加密密钥的另一个典型系统包括用于从非易失性存储器中读取一个主密钥、停止访问非易失性存储器以致直到下一次系统复位才能进行访问、并将一个来源于主密钥的灵敏数据写入一个隐蔽的地址空间、以及其中只有运行在系统的一个限定操作模式中的程序能访问在隐蔽的地址空间中的灵敏数据的加电软件。
通过将加密密钥的可用性限定到具有一个给定AppCodeDigest的应用程序上,为应用程序提供了用于控制对数据的读和写访问的一种典型方法。该方法包括一个密钥;一个具有应用程序想访问的数据的一个密封或开封格式的AppContainer;一个用于执行组成调用应用程序的部分字节的一个加密摘要来计算AppCodeDigest的CryptoGate模块;以及一个包括检查Appcontainer和AppCodeDigest的完整性校验的CryptoGate模块;以及该主密钥,用于确定该应用程序是否有权开封在给定AppContainer中的数据,或者当密封该数据时,修改它来增加完整性校验信息。
通过将加密密钥的可用性限定到在一个专用设备的应用程序上,本发明为应用程序提供了一种用于对数据的访问进行控制的方法。该方法包括公知的密钥CryptoEngine;包含一个应用程序想访问的数据的加密密封格式的一个应用程序容器数据结构;一个CryptoGate函数,在应用级程序和CryptoEngine之间截取所有访问,包括一个用于检查试图访问加密服务或数据的程序的在存储器内可执行的图像的字节的一部分的装置,并计算调用程序在存储器内的图像的字节的一部分的加密摘要来计算应用程序的AppCodeDigest;以及一个由CryptoEngine执行的完整性校验方法,用于成检查AppContainer和AppCodeDigest;以及该主密钥,用于确定该应用程序是否有权开封在给定AppContainer中的数据,或者当密封该数据时,修改它来增加完整性校验信息。
本发明还为在另一个具有一个设备管理机构的计算机的帮助下、具有一个验证服务器的另一个计算机提供了用于在一个识别装置上验证一个识别应用程序的方法。该方法包括一个登记方法、一个注册方法以及一个验证方法。
登记方法包括以下步骤a)在一个SMI中断过程中,在设备上执行第一加密操作,将生成的结果送给验证服务器,b)在一个SMI中断过程中,在设备上执行第二加密操作,对由设备管理机构产生的值进行处理,然后由该设备接收。
注册方法包括以下步骤a)在一个SMI中断过程中,在设备上执行第一加密操作,将生成的结果送给验证服务器,b)由验证服务器操作执行第二加密操作,存储所生成的加密变量用于验证方法过程中,以及c)在一个SMI中断过程中,在该设备上执行可选的第三加密操作,对由验证服务器生成的值进行处理,然后由该设备接收。
验证方法包括以下步骤a)在一个SMI中断过程中,在设备上执行第一加密操作,将生成的验证数据发送给验证服务器,以及b)通过验证服务器,对使用至少在注册方法过程中存储的加密变量从该设备接收的验证数据执行第二加密操作。
本发明还提供了一种用于在一个识别装置上验证一个识别程序的方法,或者为另一个具有一个PASS服务器的计算机提供一个用于识别该识别装置的用户的第二因子。该方法包括一个应用程序,用于a)通过涉及与一个设备管理机构和一个验证服务器的通信执行一个登记方法,以在设备上创建一个AppContainer,其中AppContainer是一个与应用程序有关的加密数据结构,以及b)存储凭证信息,其中验证服务器为AppContainer存储一个AppKey和CustAppKey。在识别设备上运行一个应用程序来执行包括下述步骤的验证方法a)开封存储凭证的AppContainer,b)修改凭证,c)重新密封AppContainer,d)将识别信息和至少重新密封的AppContainer的一部分发送给验证服务器,以及其中,在一个SMI过程中,在处理应用程序代码的同一CPU中也会发生至少部分的重新密封操作。该验证服务器a)接收识别信息和至少一部分AppContainer,b)使用识别信息查找或计算一个AppKey或CustAppKey来开封容器,c)如果开封的AppContainer具有可接受的值,则在专用设备上的专用应用程序被认为是被验证的,以及d)存储与AppContainer有关的密钥(Appkey或CustAppKey)。
为了验证、保密性、完整性、授权、核查,或者数字权利管理的目的,本发明提供了一种用于在设备上创建和利用一个或多个虚拟标记的方法。该方法包含一个用于每一种虚拟标记的应用程序、用于一个特定类型的每一个虚拟标记的一个AppContainer、一个用于计算要求CryptoEngine组件的加密服务的一个调用程序的AppCodeDigest的CryptoGate组件。
该CryptoGate组件已知一个或多个使用期长的对称密钥。通过CryptoGate访问该CryptoEngine,它已知一个或多个使用期长的对称密钥、以及一个或多个使用期长的公钥,并执行AppContainer的加密密封和开封,其中在一个SMI中断过程中执行部分加密操作。
CryptoGate组件通过核对一部分调用程序的代码或静态数据的数字签名、使用已经被载入到CryptoEngine内的一个公钥和一个AppCodeDigest值来核对调用程序的完整性。该AppCodeDigest值包括调用程序在存储器内的图像的一部分的一个最近计算的加密散列。
CryptoGate和CryptoEngine用于a)从一个主密钥和AppCodeDigest以及其它可选信息得到一个用于开封应用程序容器的密钥,b)使用所得到的密钥在AppContainer上核对消息验证代码,以及当消息验证代码正确时返回一个错误,以及c)使用所获得的密钥来对AppContainer数据解密并将其返回给应用程序。
通过与设备有关的对称密钥,本发明还提供了一种用于将私有密钥与应用程序安全相关联的方法,其中该应用程序与一个含有创建一个AppContainer的设备有关,该AppContainer包含私有密钥。
附图简要说明结合附图,参照下面的详细描述,本发明的各种特征和优点可能更容易理解,其中同样的参考数字标明同样的结构部件,以及其中

图1是说明了根据本发明原理的一个典型计算机设备管理机构系统的部件的一个简单框图;图2说明了一个客户组件层;图3说明了OSD组件的相互作用;图4是说明了多因子客户验证(MFCA)注册的框图5是说明了根据本发明原理的第一典型方法的流程图;图6是说明了根据本发明原理的第一典型方法的流程图;图7是说明了根据本发明原理的第二典型方法的流程图;图8是说明了根据本发明原理的第三典型方法的流程图;图9是说明了根据本发明原理的第四典型方法的流程图。
详细说明为了更好地理解本发明,在本说明书中使用的许多定义如下。
设备是一个包括在操作系统前执行的一个BIOS层软件环境、且当操作系统运行时可存取的计算设备,如桌上型电脑、膝上型电脑、手持的或无线的计算机。
设备管理机构包含有助于启用设备的保密特征的一个或多个服务计算机。
保密主密钥(SMK)是一个对设备,而且在某些实施例中,是对一个或多个设备管理机构机来说已知的加密变量。它可直接用作一个用于加密或完整性校验的一个加密密钥或作为计算其它加密变量或密钥的函数的输入。
一个AppCodeDigest或Application Code Digest、一个应用程序是一段程序和/或它的静态数据在存储器内可执行的的图像的部分字节的一个单向加密转换。该转换可能由如SHA1、MD5、RIPEMD160、SHA-256、SHA-512或CBC-MAC的函数完成。
AppKey(Application Key)是可直接用作一个用于加密或完整性校验的加密密钥、或作为计算其它加密变量或密钥的函数的输入的加密变量。对设备和应用程序对来说,它的值是特定的且来源于主密钥和AppCodeDigest。
CustSecret(Customer Secret)是由可能或不可能在设备上运行的应用系统的某些部件选择的一个加密变量。在特殊的企业中,它与验证服务器有关,而且在该企业域中,它可能与一些用作应用程序验证的设备有关。
CustAppKey(Customet Application Key)是一个来源于Appkey和CustSecret、并可直接用作一个用于加密或完整性校验的加密密钥或作为计算其它加密变量或密钥的函数的输入的加密变量。
Appcontainer或Application Appcontainer是能使用CustSecret或Appkey来加密密封或开封的一个数据结构,其中密封操作是为密封容器的应用程序的识别提供保密性和完整性校验以及可选择的验证。
CryptoEngine(Cryptographic Engine加密驱动程序)在一个只有在开电自检和经过CryptoGate才能得到的受保护的环境中执行加密操作,能存储和调用高完整性的公钥、存储至少一个使用期长的对称密钥(SMK)、从该使用期长的对称密钥得出对称密钥、执行对称加密(包括完整性和保密单元)以及公钥的加密、生成伪随机数、可选地加密保密密钥、并具有其它加密支持函数如密钥生成和输入及输出密钥。
CryptoGate(Cryptographic Gatekeeper)截取所有的在应用级程序和CryptoEngine之间的访问,并能为企图访问加密服务或数据的程序检查程序和/或它的静态数据在存储器内可执行的图像的部分字节。
AuthBuffer(Authorization Buffer验证缓冲器)是一个允许一个专门的应用程序执行由Cryptogate和/或CryptoEngine提供的一套操作的数据结构,其中该数据结构包括AppCodeDigest和组成包括在代码摘要中的部分的应用程序代码及静态数据的部分说明,而且它包括一个能由CryptoEngine验证的数字签名。
MAC(Message Authentication Code)是一个能用来核对消息或数据结构的完整性的值,以要求用并不太公知的一个加密变量的方式在消息的部分字节上计算它。为此公知的算法包括CBC-MAC、DMAC以及HMAC(基于公知的散列函数如MD5和SHA1)。
SMI(System Management Interrupt系统管理中断)是由大多数的CPU支持的一个中断属性,允许BIOS级软件获得一个对CPU和在SMI模式外不容易有效的一个永久的存储地址空间的排他性访问。
将首先描述本发明的高级设计。通常,计算机设备管理机构系统10的结构包括一个或多个设备管理机构、客户加密驱动程序(CryptoEngine)、理想使用BIOS、被锁的非易失性存储器以及系统管理模式(SMM)、操作系统驱动程序(OSD)、启动的客户应用程序(Apps)、验证服务器(PASS)以及启动的服务器应用程序。
在客户设备和登记服务器之间提供在线登记过程。交易级应用程序接口(API)为客户服务器应用程序提供扩展的设备管理机构函数。该系统为在线的客户/服务器应用程序和离线的独立函数提供安全函数。
验证服务器是任何加密启动的服务器应用程序的组件。它的主要的目的是执行与安全设备启动的应用程序有关的加密函数。为执行上述函数,验证服务器密封和开封与一个加密启动的客户进行交换的容器,在需要时利用一个或多个设备管理机构服务器的帮助。验证服务器保持关键ID值表。
设备管理机构服务器主要处理设备识别和密钥的登记。在某些实施例中,设备的保密主密钥是设备和一个或多个设备管理机构之间的共享的秘密。在这种情况下,设备管理机构必须执行所有的需要访问表示验证服务器和其它应用服务器的安全的主密钥的加密操作。
本发明提供对AppContainers的支持。设备管理机构将AppKeyPart发送给验证服务器。服务器执行一个允许创建AppContainers的算法。该算法要求访问保密主密钥(SMK)和AppCodeDigest(ACD),并在存储保密主密钥的计算机上调用它。设备管理机构规定如何在客户PC上调用应用程序以及如何用操作系统驱动程序登记。只要通过设备管理机构服务器创建了第一AppContainer,这就可以从任何服务器在线完成。
公用程序为应用程序创建AppCodeDigests,当希望运行该应用程序时,这些公用程序可以在相同的操作系统上运行。用于应用程序的AppCodeDigests被存储在相对于应用程序的一个新表中的一个数据库中。AppCodeDigests可存取用于生成AppContaiers。为服务器生成公开/私有密钥对。使用密钥生成软件理解的标准来输入和输出密钥对。使用有标记的密钥对对数据进行标记。
另外,在本发明中使用了几个客户加密驱动程序(CryptoEngine)的实施例,它利用在标准的个人电脑上可获得的不同硬件特性。
图1是根据本发明的原理,说明了一个典型的计算机设备管理机构系统的组件的简单框图。本发明的首选实施例包括一个由复位时打开的锁存器保护装置(OAR-lock)14保护的非易失性存储器(NVM)11、一个BIOS ROM系统初始化模块12、一个经过系统管理中断(SMI)从系统的正常操作模式访问的系统管理模式(SMM)16。
受保护的非易失性存储器11用来存储保密主密钥。BIOS系统初始化模块12负责安全地将保密主密钥从非易失性存储器11传送到SMRAM13中,它是一个受保护的存储器区域,只能从系统管理模块12可寻址。当保密主密钥传送到SMRAM13以后,系统初始化模块12关闭锁存器14使非易失性存储器11直到下次系统复位时才能被运行在系统中的程序15访问。保密主密钥只有在系统的正常操作过程中,在隐蔽的SMRAM16中才有效。
OAR-lock保护装置14防止通过除了启动时运行的ROM系统初始化模块12外的任何程序14来读取非易失性存储器11。当读取非易失性存储器11后,系统初始化模块关闭锁存器14以使非易失性存储器11直到下次系统复位时才能访问,在该时间段,系统初始化模块12重新获得控制权。
当OAR锁定的非易失性存储器11不再有效时,使用它的一个选择是在BIOS ROM根模块中存储一个共享的保密主密钥,其中的BIOS ROM根模块通常是在BIOS系统初始化模块12中的系统启动时的开电自检操作后、通过系统映射成不可寻址的16K字节区域。在用不同的可靠级启动系统后,还存在通常不能由应用程序访问的其它存储单元。
SMI模式是具有附加的唯一的属性的Intel x86兼容处理器的专用模式。软件调试程序不可能单步跟踪SMI模式,除了在SMI模式中时,也不可能浏览SMI存储器。该模式用于在计算机的正常操作过程中在客户PC上隐藏保密主密钥,并为各种对计算机有效识别所需的安全目的使用该保密主密钥。
对于系统10的操作来说,上述所述的特殊特征(BIOS ROM代码、OAR锁定的非易失性存储器11、以及系统管理模块16)并不是绝对需要的,但它们一起为该系统提供了保密操作的最高级的可靠性。
在可选的纯软件的实施例中,用更低级的可靠性,提供了相同的函数操作。在这种情况下,操作的限定模式是标准的“ring zero”操作系统保护程序,其中在被称为操作系统驱动程序的系统设备驱动程序内执行CryptoEngine函数。因为操作系统驱动程序不是在SMI模式中运行,因此它就不会同增强的BIOS产品一样安全。因此专门的额外修改和模糊技术被包含在产品的纯软件形式中用来防止保密主密钥被发现或拷贝。另外,因为保密主密钥存储在文件系统中而不是主板上,因此将附加的设备检测加入到操作系统驱动程序中来将保密主密钥赋值给个人电脑。
另外,在纯软件的系统没有运行在SMI模式的实施例中,代码包括对反向工程师和“破解”来说用于使其更为困难的特定特征。
在CryptoEngine的各种软件形式中,使用了各种技术为保密主密钥和核心加密操作提供更强大的可能保护。
本发明提供保密主密钥和设备绑定。在保密主密钥和计算机之间有关联,以至使保密主密钥不能从一台计算机传送给另一台。这种关联基于计算机的规格,并在不丢失使用该保密主密钥的能力的前提下,允许用户慢慢地更新它们的计算机。当该主密钥被赋值给系统中的专门的磁盘驱动器时,重新格式化硬盘驱动器或用另外的系统替换将禁止该保密主密钥的使用。
本发明提供那有限的保密主密钥和会话密钥暴露。当把它们用在任何操作时,这种设计限制了保密主密钥和会话密钥的暴露。
本发明提供了破解抵抗方法。由于软件CryptoEngine可能具有在SMI存储器中隐藏保密主密钥的能力和不能象BIOS一样在SMI中浏览代码操作,软件CryptoEngine代码使用附加的方法来防止破解。另外,软件CryptoEngine使用用于存储保密主密钥的技术来防止通用的程序确定该保密主密钥。
现在将讨论设备管理机构的概述。设备管理机构组件执行下面的功能。设备管理机构通过特别为应用程序和设备对提供一个AppKey来登记一个设备并存储它的SMKm登记应用程序。这里将简单地解释设备管理机构和附属模块并在后面做详细地说明。
客户应用程序是一个加密启动的应用程序,通常运行在基于微软视窗的个人电脑(PC)上。客户应用程序允许用户测试该设备是否已登记、登记该设备和显示Key ID、在设备上注册应用程序、生成包括Creat、Edit、Delete的ApopContainers、将AppContainers发布到验证服务器、从验证服务器获得AppContainers以及不登记该设备。
验证服务器是一个客户/服务器加密启动的应用程序的服务器部分的一个组件。它负责验证从客户端传送的信息。验证服务器是从客户设备接收登记请求、从应用程序登记模块请求AppKey并存储该AppKey、创建AppContainer并发送到客户设备端、提供用户接口(UI)以通过一个UI生成AppContainers(Creat、Edit、Seal和Unseal)、从客户设备接收AppContainers的软件组件。
设备管理机构由几个组件组成并至少具有下面的功能。一个登记模块接收请求去登记一个设备。它拒绝客户保密主密钥的一半,并生成返回给客户设备的另外一半保密主密钥。应用程序注册模块为AppKeys接收请求、构造该AppKeys并将它返回给调用程序。
现在讨论一个典型的用户经历。当测试一个包括设备管理机构的系统时,用户期望执行操作指令。基本的概念是用户登记一个客户设备(运用设备管理机构的登记模块)、注册一个应用程序然后在那个设备上创建、编辑、密封和开封Appcontainers(运用设备管理机构的应用程序注册模块)。用户还能将Appcontainers发送给其中能用由应用程序注册模块生成的AppKey对它进行操作的验证服务器。验证服务器功能由设备管理机构激活。
一个典型的方案是客户PC<__>应用程序注册和AppContainer传送<__>经过服务器客户PC<__>登记<__>设备管理机构服务器下面是用户运用该系统所执行的操作。
在客户端所做的设备登记如下所述。为登记该设备,用户使用客户应用程序执行下面的操作。
用户对登记进行测试。通过对登记选项的测试就能保证该设备以前没有被登记过。如果该设备已经登记过且用户希望重新登记,则选定应用程序中的未登记选项。
用户选择一个登记设备选项。该选项与登记服务器联系并为该设备生成一个保密主密钥。该保密主密钥将返回给客户PC并存储(它被存储在哪儿依赖于所使用的加密系统的版本)。出现的对话框表明该设备已经登记。
用户在设备管理机构日志中校验一个新的保密主密钥已经创建。用户能使用在设备管理机构上的登记用户接口检验以表明已经创建了一个新的保密主密钥。
在客户端的应用程序注册如下所述。为进行下面的操作,用户必须具有一个已登记的客户设备。
用户开始注册。用户选择注册项来开始注册。此时提示用户为应用程序和设备组合输入标识符(ADID)。
通过验证服务器将注册请求发送给应用程序注册模块。应用程序注册模块生成一个AppKey,然后将它返回给验证服务器。
用户可能核对应用程序注册模块日志。用户使用应用程序注册模块用户接口核对已为该应用程序生成了AppKey。
用户可能为注册核对验证服务器日志。用户为运行在设备上的应用程序的实例核对该验证服务器现在有一个AppKey。
用产可能在客户设备上检验现在具有一个AppContainer。通过在客户设备上的AppContainer菜单,用户看到一个他已经具有一个AppContainer的直观确认。
在客户设备上的AppContainer操作如下所述。下面将讨论在客户设备上运用AppContainerer能作什么。在注册以后,用户将在一个设备具有由验证服务器创建的一个AppContainer。
在客户端上提供的选项允许用户将AppContainer发送给服务器以及下面将描述从验证服务器请求一个AppContainer,这将在以下进行描述。这些选项的目的是提供一种用于说明在客户和验证服务器之间的一个典型交易的方法。用实例解释是最好的方法。
用户想为在他的客户PC上的虚拟现金抽屉增加钱。当前的结算存储在AppContainer中。用户在现金抽屉应用程序中选择一个增加现金的选项以及与AppContainer一起发送给运行在验证服务器(由一个现金抽屉提供者运行)的AddCash脚本。打开AppContainer,改变数据并将它返回给用户,在同一交易中这些操作都是可能的。
在本系统的一个实施例中,设备管理机构用户能看到在客户和验证服务器之间将发生什么,并在他自己的设备上操作AppContainer、并以他自己的速度增加数据和校验日志等。因此代替一个将AppContainer发送给服务器、改变预定义的数据并将其返回给客户的基本交易,而是提供了一个让这个工作由用户从客户设备启动的功能。用户能在客户端选择一个选项来将AppContainer发送给服务器。然后用户能转到服务器,校对它是否在那儿,在它中改变一些数据并重新密封它。然后用户回到客户PC并返回该AppContainer。
在本发明的首选实施例中,用户弹出数据而不是让服务器将容器推回。
在客户应用程序上有一个AppContainer菜单允许用户列出AppContainer、编辑一个AppContainer、将一个AppContainer发送给验证服务器、从验证服务器接收一个AppContainer、创建一个AppContainer以及删除一个AppContainer。
列出AppContainer。所有的AppContainer由应用程序存储在客户设备上的一个缺省目录中。选择列出AppContainer选项允许显示所有的容器(可能具有某些用于识别创建它们的应用程序的数据)。用户能突出显示列表中的一个AppContainer,然后选择下面两个选项中的一个编辑AppContainer。应用程序警告用户AppContainer当前是密封的,并提示他选择尝试和开封它。如果开封成功则在文本框中显示AppContainer的内容并能进行编辑。如果用户改变了任一AppContainer,则关闭AppContainer,将给他一个密封AppContainer的选择。
将AppContainer发送给验证服务器。用户将AppContainer发送给验证服务器。这允许用户转到验证服务器并尝试操作该AppContainer。
从验证服务器获取AppContainer。用户能从验证服务器请求一个特定的文件。
创建AppContainer。用户应该能创建他自己的AppContainer。当用户选择该选项时,可得到与上面所述的编辑AppContainer选项相似的能力。
删除AppContainer。这并不是一个加密功能但对帮助整理系统是有效的。
现在将讨论在验证服务器上所做的AppContainer操作。验证服务器提供允许用户完成各种任务的两个用户接口(AppKeys日志和AppContainer)。
该AppKeys日志用来向用户表明当请求一个AppKeys时实际上发生的事。它不允许用户对该信息做任何的操作。它可能是一个日志浏览器,用来表示用一个标识符从客户设备接收了一个AppKeys请求和存储了该AppKeys。它可能表示如日期/时间、请求客户设备的IP地址、KID、所得到的AppKeys等等的信息。
AppContainer用户接口提供了与那些客户设备应用程序相似的选项。用户能列出AppContainer、创建一个AppContainer以及删除一个AppContainer。
列出AppContainer表示列出所有和它们所属的应用程序的标识符一起存储在验证服务器上的AppContainer。选择一个AppContainer,引出能提供编辑AppContainer的内容的另一页。
使用创建AppContainer,用户为客户设备(设备当时请求)创建AppContainer。该删除AppContainer功能并不是加密功能但有助于帮助整理该系统。
登记和应用程序注册模块具有一个提供了有关所请求的主密钥、AppKeys等的信息的用户接口/日志浏览器。
现在将讨论加密服务器的设计。该服务器具有分解功能以方便各种组件的保护。主要的想法是密钥从不转到任何网络。
该组件包括密钥、加密库以及一个登记代码。密钥(保密主密钥、服务器私有密钥)最好存储在结合了各种加密功能组合和密钥数据库的保密盒中。加密库为验证服务器提供了用来在各种容器中执行最初的操作(enc、dec...)的必要的程序。登记函数生成在系统中最敏感数据当中的保密主密钥、秘密。登记代码保护该保密主密钥并将它们安全地送到登记客户设备。
加密服务器的逻辑配置如下所述。
在防火墙和载入均衡器之后是HTTP服务器一运行Enrollment.protocolHandler(+容器类)的服务器。在另一个逻辑防火墙后用来防止密钥服务器接收未验证的信息是具有运行Enrollment.getSmk(+容器类)的密钥数据库的密钥服务器和RSA-Bsafe加密数据库加密服务器保密地存储三种用于代码标记、通信和根密钥的私有密钥。根密钥用于标记新的低级密钥。这些密钥存储在一个加密文件中并在启动时由加密模块载入。
在与每一位客户登记时生成的保密主密钥存储在数据库中。设备管理机构生成保密主密钥。该代码从登记的一个小服务程序/协议处理部分接收一个public(mkc(clientSeed))。
设备管理机构所要求的基本的功能是处理登记请求。Enrollment.protocolHandler函数从网络获得容器并将它们传送到加密服务器,以便enrollment.genSmk代码能在对任何其它部分都不暴露任何密钥信息的情况下完成它的工作。
下面将详细讨论部件。
登记。登记的处理流程如下(1)由一个客户调用一个登记小服务程序。
(2)登记小服务程序通过RMI在保密服务器上实例化Enrollment类。将InputStream作为一个自变量传送给保密服务器上的一个Enrollment对象。
(3)然后,Enrollment对象在保密服务器上进行用接收到的InputStream构造一个PubKContainer类作为一个构造函数变量。
从PubK容器得到一个MK容器的实例。
从MK容器提取SMK客户籽数。
产生一个随机的SMK服务器籽数(如SMK的服务器部分)。
将SMClientSeed与SMKServerSeed连接起来生成主密钥。该连接是按SMClientSeed+SMKServerSeed的顺序连接。
在MK容器对象中设置适当的操作码和数据(SMKServerSide)。
通过在上述步骤中形成的主密钥上执行SHA1来生成一个Key ID。
将主密钥和Key ID转换成BigIntegers,并将它们存储在数据库中。密封所获得的MKContainer对象。
得到以从保密服务器发送到Web服务器(即到调用登记小服务程序)的字节数组格式的原始数据。
登记小服务程序将原始字节转换成InputStream,并将它作为Http应答发送给客户。
上述的流程是一个简单的实施例。在首选的实施例中,一个应答小服务程序等待一个客户应答(已经成功地接收了SMKServer籽数)然后为永久的保密主密钥更新数据库表。
现在将详细地讨论模块组件。
客户应用程序是一个通常运行在基于微软视窗的PC上的应用程序。为使该应用程序使用加密功能,将它连接到由操作系统驱动程序调用的内核模式(Kernel Mode)设备驱动程序上。
该应用程序提供以下的功能初始化、Enrollment检验、登记该设备、在设备上注册应用程序、列出AppContainers、编辑AppContainers、保存AppContainers、将AppContainers发布给验证服务器、从验证服务器获取AppContainers、创建一个新的AppContainers以及不登记该设备。
至于初始化,当调用应用程序时,它自动按如下进行载入操作系统驱动程序并调用OsdRegisterApplication以将应用程序设置为一个注册的应用程序。
在登记检验中,调用OsdGetCapabilities核对返回的Capabilities参数以便观察该设备是否已经注册,并显示一个对话来表明该设备是否注册。
为登记该设备调用OsdEnrollGenerateReqest来获得一个密封的PubKContainer、将HTTP请求发送到设备管理机构Enrollment URL、请求体中传送在PubKContainer、核对该应答代码以确保操作成功。如果成功,则将返回的内容传送作为调用OsdEnrollProcessResponse中的MKContainer参数,并显示一个对话框以表明登记是否成功。
为在设备上注册一个应用程序,调用OsdGetCapabilities并核对返回的该Capabilities参数以便观察设备是否已经登记。如果没有,则用上面所定义的方法登记该设备。提示用户一个用于识别应用程序/设备结合(ADID)的字符串。创建一个将被用于注册的PubKContainer。将HTTP请求发送给设备管理机构RegisterApp URL,并在请求体中发送PubKContainer和ADID。核对应答代码以确保操作成功。如果成功,则产生的数据应为AppContainer。在缺省的目录中存储AppContainer。
用户能用高亮显示一个AppContainer的方式显示存储在缺省目录中的AppContainer的列表。
客户应用程序提供以下能力(通过菜单选项、按钮等)编辑高亮显示的AppContainer、删除高亮显示的AppContainer、将高亮显示的AppContainer发送到验证服务器以及创建一个新的AppContainer。
为编辑一个AppContainer,首先通过调用一个OsdAppContainerUnseal函数、传送AppContainer文件pContainerBuffer参数来开封AppContainer,以及如果OsdAppContainerUnseal不成功,则显示一个错误对话框。分析AppContainer结构以获得数据字段。在一个允许用户修改数据的编辑框中显示AppContainer的内容。提供保存或放弃这些对AppContainer的修改的能力。
为保存AppContainer,密封AppContainer、重构AppContainer数据结构、调用OsdAppContainerSeal函数、发送pContainerBuffer参数中开封的OsdAppContainerSeal结构的内容,以及如果OsdAppContainerSeal不成功,则显示一个错误对话框。将密封的AppContainer结构保存到文件中。
为将AppContainer发布到验证服务器,将HTTP请求发送到URL使HeresAnAppContainerForYa函数在请求体中传递高亮显示的AppContainer文件的内容,并核对HTTP请求的状态,以及显示一个对话框表示成功或失败。
为从验证服务器获得一个Appcontainers,提供一个对话框来允许用户在服务器上选择打算下载的文件。将HTTP请求发送给URL使OiGiveMeAnAppContaier函数在请求体中传送所请求的Appcontainers的内容。核对HTTP请求的状态并显示成功或失败的对话。如果打算覆盖一个文件则提示用户覆盖原文。
为创建一个新的Appcontainers,打开一个已存在的Appcontainers文件、开封该Appcontainers、以及将数据块置0、并允许用户编辑该数据,然后跟随SaveAppContainer函数(将该文件保存为一个由该用户指定的新的文件名)。
为不登记该设备,调用OsdRegisterApplication以将应用程序设置为一个注册的应用程序。调用OsdGetCapabilites来核对所返回的Capabilities Word以便观察设备是否已经登记。如果设备已经登记了,则调用OsdInvalidateSMK。
由验证(PASS)服务器提供的功能如下所述。验证服务器能注册设备/应用程序组合。客户设备用请求体中的PubKContainer和ADID向OiRegisterMe函数的URL发送一个请求。验证服务器给ARM服务器发送和转换该请求。ARM服务器产生和返回相对于ADID、应由验证服务器存储的一个AppKey。然后验证服务器使用最新生成的Appkey创建一个AppContainer并将它发送回客户设备。注册就算完成了。上面所述的操作均是在客户、验证服务器和应用程序注册模块之间的单个交易中完成的。
验证服务器提供一个用户接口以便通过用户接口来操作AppContainers(Creat、Edit、Seal和Unseal)。验证服务器提供一个允许用户操作AppContainers的用户接口。这可以通过使用HTML和具有用Java写的代码的Java Servelts来完成,以便允许密封和开封AppContainers等等。正如有关运行在客户端的应用程序的部分中所定义的那样,需要页来列出(List)和编辑(Edit)AppContainers。
验证服务器能从客户设备接收AppContainers。客户设备具有一个允许将AppContainers发送给验证服务器的功能。存在于验证服务器上的入口点允许这种情况的发生。这可通过使用一个从输入流读取并将数据连同文件名存储在文件中的小服务器程序、或甚至更简单地通过激活验证服务器上的HTTP的PUT方法来完成。
现在将讨论容器和密钥。容器是用于保存信息的结构。能标记和/或加密该信息。为增加保密性,可使用各种类型的容器。有些容器仅可用做标记数据。有些容器保存加密的数据。甚至在加密的容器中,它们是依赖于所使用的加密算法的子类型。有四种类型的容器。
SignedContainer保存由私有密钥(来源于标记的密钥对)数字标记、并可用匹配的公开密钥(在客户端公开密钥存储在ROM/闪存中)验证的数据。这些用来将验证后的数据从设备管理机构服务器发送到客户机,并用来授权软件模块使用设备管理机构客户服务。
AppContainer是一个只能由运行在一个特定计算机上的专用应用程序读或写的受保护的容器。这些容器识别密封它们的程序,并可能允许其它的程序开封一个容器,因此它们能用作进程间通信的保密格式。象检测病毒改变那样的高级安全功能、软件许可和安全钱包能建立在AppContainer的顶部。通常通过使用保密主密钥的派生物用于加密来将AppContainer赋给一个给定计算机。
PubKContainer是由客户(OSD)用一个RSA公开密钥(来自通信密钥对)密封和只有通过具有匹配的公开密钥的接收器(通常是设备管理机构服务器)读的一个数字信封。这些在登记过程使用,并用于在客户和验证的设备管理机构服务器之间建立一个加密的通道。在这个容器内的数据是用通过操作系统驱动程序随机生成的128位加密密钥(也称为产品内的一个主密钥)进行加密的。RC6密钥(主密钥)和客户的Key ID (KID)是用接收器的公开密钥(服务器通信PubKey)加密的。
基于对这个容器的写和读程序来说已知的主密钥(由客户创建和以一个PubKContainer发送)MKContainers用作一个数据信封的一部分。在经由PubKContainer将主密钥发送给服务器后,这些可用于在客户和设备管理机构服务器之间的安全通信。也可用于保护客户计算机上的局部数据。
这些容器结构具有一组能在它们上执行的预定义操作。这些操作是密封或开封的。
密封能不加密地标记(正如证书具有大学的图章,但任何人都能阅读证书的内容)。密封也能加密(正如含有一个奖品的优胜者的信封是密封的,因此如果不开封的话,没有人能看到内容)。
开封是密封操作的逆过程。这能证实图章是原始的(正如证书上的图章,它们具有某些几乎不可能复制的能被检验的特征)。开封也能暴露隐藏的内容(就奖品来说,获得隐藏的内容是相当容易的)。
每一个容器结构如下所述。在密封操作描述之后,容器结构显示在它的开封版本中。因此密封的结构是随着开封操作的描述来显示的。如果因为任何原因一个操作失败。则将容器置0。
下面逐条列举由本发明提供的功能。一小组的容器类型支持a)通信安全,b)系统完整性,以及c)应用程序专门保护的容器。由本发明提供的功能允许人们在客户和设备管理机构服务器之间创建一个保密主密钥以便允许数据容器或命令的创建只能在特定的设备上有意义,基于程序而不是用户的标识控制的数据的访问,验证来源于一个经授权的设备管理机构服务器的信息、验证来源于特定设备的信息,支持用于需要保存捣毁证据保密的应用程序的受保护的处理环境,以及支持只能由特定程序覆盖的数据存储区域。
现在将讨论本发明的设计的概述。受保护的容器由低级BIOS代码和OS层驱动程序(OSD)代码(如,Win98下的VXD)实现。有些BIOS代码在POST过程中运行以在系统管理存储器(SMM)中建立经由系统管理中断(SMI)调用的程序使用的信息。SMI程序使用来自闪存的公开密钥执行RSA操作,因此很难篡改。SMI程序也隐藏和管理对设备和设备管理机构服务器来说公知的一个保密RC6密钥的保密主密钥。加密原语从这个单一的128位主密钥中导出多个密钥,其中每个密钥用于单个目的。SMI程序验证它们的调用程序,而且仅执行用于一个经授权的操作系统驱动模块的服务。
所有的客户都了解服务器的公开密钥,因此它们能检验服务器标记了一条信息,这是因为服务器是唯一知道匹配的私有密钥的一个。保密主密钥对每一个设备来说是唯一的,而且仅有那台设备和服务器知道。如果消息由保密主密钥适当地保护,则该消息一定来源于具有唯一保密主密钥的服务器或客户。客户使用一个作为保密主密钥的SHA1摘要的20字节密钥标识符(Key Identifier)来识别它们。在下面这个意义上来说,SHA1函数是单向的,即在已知Key ID、而不是试每一个可能的主密钥去观察是否能生成有效的Key ID,对攻击者寻找保密主密钥来说毫无帮助。有非常多的保密主密钥值(2到128th幂)接近实际。
在保密主密钥的帮助下,AppContainers是安全的。每一个容器用一个密钥进行加密,其中该密钥是保密主密钥和属于该容器的程序的代码摘要的一个函数。该设计保证了SMI级代码仅为用于创建该容器的程序开封一个容器。创建用在特定计算机上的特殊程序的第一容器必须包括设备管理机构服务器。
中级操作系统驱动程序代码支持容器抽象,并执行对SMI程序来说不可能的操作。例如,SMI程序不能接收缺页,因此操作系统驱动程序必须在调用SMI程序前将参数拷贝到锁定的存储器中。操作系统驱动程序也能比SMI程序运行更长的时间。
操作系统驱动程序支持可能的由作为WDL一部分的序列发生器下载的容器函数。安装和初始化WDL的过程包括建立受保护的容器所请求的主密钥。
用于支持本文中安全特性的协议严重依赖于本文中所述的四种类型的容器。例如,创建主密钥的登记协议是基于将这些容器与设备管理机构服务器交换。
系统使用加密密钥以便在客户系统它本身以及客户和设备管理机构服务之间提供程序和数据的私有性、完整性和验证。下面将讨论存在的密钥和如何使用它们去建立信任和安全。
在本发明中使用了公开/私有密钥对。公开/私有密钥对被用于安全地处理不需要与特殊的客户系统关联的数据。这些主要用来保证数据从任何客户端传送到设备管理机构服务器、以及与此相反传送的数据是可信的,而且将有助于数据是私有的(加密的)。在制造过程中,这些密钥存储在ROM中。
设备管理机构服务器保存用于不同目的和存储在服务器环境中不同位置的三个RSA密钥对的私有密钥。客户机系统保存这些密钥对的公开密钥并存储在ROM中。使用这些密钥对的每一个标准的加密1024位版本。这三个密钥对是根密钥对(Root Key-Pair)。私有密钥存储在由未连接到Internet的设备管理机构控制的一个计算机中。匹配的公开密钥存储在客户计算机的ROM中。私有根密钥用来标记新的公开密钥,然后将它们发送给客户计算机来替换旧的公开密钥。这些根密钥很少使用。公开密钥与带标记的容器一起用在客户机系统中。
服务器通信密钥对。这也被称为封装密钥对,并被用作动态数据标记。私有密钥存储在设备管理机构服务器上并用来与客户建立安全通信。私有密钥能用来开封由客户发送的密钥(以及其它任何的数据),或动态地标记所创建的将由客户检验的消息。它与PubKContainers一起使用。所有的客户具有一个存储在他们的BIOS ROM中的匹配的公开密钥的拷贝。
带标记的密钥对。存储在设备管理机构标记的计算机上的私有密钥不能直接由Internet访问。私有密钥用来标记下载的文件(程序和配置数据),然后将它放置在设备管理机构服务器上并最终将它发送给客户计算机。所有的客户计算机具有匹配的公开密钥,因此它们能检验由私有密钥创建的签名。标记密钥对大量地用来验证静态信息,如新发行的软件组件。由于私有密钥不能从Internet访问,因此它就更容易保护。
公有密钥用在带有标记的容器的客户系统中。对上面所有的操作,有可能只使用一个密钥对。然而,为不同目的使用不同的密钥对很廉价且容易降低成功地摧毁整个系统的攻击的可能性。
保密密钥。由于相同的密钥可用在加密和解密中,因此下面的密钥是对称密钥。
主密钥被用作创建在加密/解密中使用的对称密钥的基础。在客户和服务器之间单独通信的过程中,通常使用这些密钥。它们等同于对话密钥。
保密主密钥用来安全地处理数据,它需要与特定的客户系统相关联。该保密主密钥是唯一的且用来验证该客户系统。因为它唯一地识别该客户系统,因此加密主密钥是很重要的。它被用作创建用在加密/解密算法中使用的其它对称密钥的基础。在登记过程中创建保密主密钥并通过设备管理机构服务器发送给客户。
主密钥只能由设备管理机构服务器以及在客户系统上的加密的ROM组件中访问。ROM组件运行在系统管理模式中(SMM),它是用于x86处理器的一个特定的模式,且不能由软件反汇编程序跟踪。
保密主密钥用在客户系统上来密封和开封AppContainers。保密主密钥赋给一台计算机且一定不能变换(除非是如果先将它传送给设备管理机构服务器然后传送给另一个客户)。在正规的系统存储器中,不可能暴露保密主密钥。因此它不应该能被黑客截获和传送给另一个计算机的操作系统驱动程序级。密封和开封AppContainer的操作应该严格地在SMM中执行。用来密封和开封的所有其它操作可能由操作系统驱动程序层执行。
密钥标识符(KID)是保密主密钥的单向的SHA1摘要。该Key ID用来识别在从客户发给服务器的信息中的客户。来源于客户的信息头部包括Key ID,服务器将使用它在保密主密钥数据库表中寻找与客户的主密钥对称的密钥,然后依次用来导出解密其它的信息的密钥。当登记过程没有指定保密主密钥时,保密主密钥用一个临时的随机的值代替直到用真的保密主密钥代替它为止。
一定数量的导出的密钥基于保密主密钥和其它主密钥产生。用于导出密钥的原语表明基于下面将描述的密钥用法值的那些导出的密钥是如何产生的。
Key Usage Value(密钥用法值)。这一段列举了作为本设计的一部分的密钥用法值。这些值与NewKey()函数和Enc()Dec()函数一起使用。这些值在各种容器的密封和开封过程中使用。对客户和服务器来说,用法是不同的(这使得再现和自再现攻击变得复杂)。
用法名称注释UsageAppCodeDigest 用来为一个AppContainer的AppCodeDigest字段创建加密密钥UsageAppEncServer 用来为由服务器创建的一个AppContainer创建加密密钥UsageAppEncClient 用来为由客户创建的一个AppContainer创建加密密钥UsageAppMacServer 用来为由服务器创建的一个AppContainer创建HMAC密钥UsageAppMacClient 用来为由客户创建的一个AppContainer创建HMAC密钥。
UsageMKEncServer 用来为由服务器创建的一个MKContainer创建加密密钥UsageMKEncClient 用来为由客户创建的一个MKContainer创建加密密钥UsageMKMacServer 用来为由服务器创建的一个MKContainer创建HMAC密钥UsageMKMacClient 用来为由客户创建的一个MKContainer创建HMAC密钥用在AppContainer中的密钥被分成三部分。AppContainer的一个重要的特征是用来创建它们的AppKey( )是保密主密钥(即客户设备的唯一标识符)和应用程序代码摘要(即“拥有”容器的软件的唯一标识符)的一个函数。AppContainer被赋于一个特定设备上的专用程序。密钥的最后一部分对设备管理机构(不象保密主密钥那样)和普通的公众(不象应用程序代码摘要)来说并不可知。该最后部分被称为CustomerSecret。该密钥的任何值能用来密封AppContainers。但建议使用强大的128位随机值(如保密主密钥一样强大)。
CustomerSecret部分允许企业放弃折衷的应用程序容器而不必获得一个新的构造用于产生一个不同的应用程序代码摘要的应用程序。同时,该CustomerSecret允许在设备上的一个给定应用程序实例(即安全登录应用程序)与不只一个的服务器安全地共享数据。每一个服务器将与相同设备上的相同应用程序建立一个唯一的CustomerSecret。因此,如果提供正确的CustomerSecret,就只能解密密封的AppContainer。
CustomerSecret用于在特定的客户应用程序和与客户应用程序连接的多个服务器中的一个之间进行共享。
通过向卖主提供用于向设备管理机构登记的一个AppKey值的列表,设备管理机构服务器可能委托管理机构为软件的特定卖主创建AppContainers。AppKey是保密主密钥和应用程序代码摘要的一个加密的单向函数,因此不需要卖主为其它的应用程序创建容器和卖主不能轻易地了解某一给定设备的主密钥的情况下而为卖主提供这些密钥。
现在将讨论Container Opcodes(操作码)以及Formats(格式)。所有的容器具有一个公用的4字节头部,它包括一个操作码字节(命令或消息类型)、一个格式字节、以及一个具有下面所述内容的长度(length)字(16位)。格式字节表明所提供的容器的四种类型,因此低级程序知道应该执行何种类型的加密操作。如果在将来的版本中加密算法改变,则格式字节也将改变。操作码字节表示容器内的高级数据的类型。低级程序使用某些操作码值(例如,用于在登记协议中使用的容器),但是大多数对由高级代码和未来版本使用都有效。Length字段识别属于容器的字节数目(头部后)。不加密头部,但它由作为每一个容器一部分的加密校验和进行保护。
该章节列举了定义的容器操作码和具有该操作码的容器的格式。在当前的版本中,每个操作码包含一个特定的容器格式,虽然将来可能会改变。同时具有opcode字段和format字段的目的是简化操作码分级和允许将来在加密算法组中的改变,或者用于在为一个特殊操作所请求的数据内容中改变。
Format字节具有下述值中的一个。
Format代码值 说明FmtSignedContainer1容器是一个Signed(带标记的)ContainerFmtAppContainer 2容器是一个App ContainerFmtPubKContainer 3容器是一个PubK Container
FmtMKContainer 4 容器是一个MK Container下面是OP代码的值OP代码名称 值OPC_OSD_AUTHORIZATION 0x01OPC_OSD_ALLOW_TRANSFER 0x02OPC_MK_KEY 0x03OPC_INITIAL_APP_CONTAINER_FROM_SERVER 0x04OPC_CUSTOM_APP_CONTAINER_DATA 0x05OPC_CHALLENGE_RESPONGSE_FROM_CLIENT 0x06OPC_SMK_ENROLL_REQUEST_OUTER0x07OPC_NEW_CONNECTION 0x08OPC_SMK_ENROLL_REQUEST_INNER0x09OPC_SMK_ENROLL_RESPONSE 0x0aOPC_CLIENT_TO_SERVER_WRITE 0x0bOPC_SERVER_TO_CLIENT_WRITE 0x0cOPC_CHALLENGE_REQUEST_FROM SERVER 0x0e现在将讨论SignedContainers的操作码。SignedContainers保存由私有密钥(来自于带标记的密钥对)数字标记,并能用匹配的公开密钥(在客户端公开密钥存储在ROM中)验证的数据。这些被用来将验证数据从设备管理机构服务器发送给客户计算机,并授权软件模块使用客户服务。
Opcode(操作码)OpcOsdAuthorization Container(容器)FmtSignedContainer该容器用来授权一个程序使用操作系统驱动程序安全模块的一些和全部函数。在容器的数据部分具有以下的字段字段长度 说明NstartOffset4字节 调用代码的起始偏移量NendOffset 4字节 调用代码的结束偏移量CodeDigest 20字节调用代码的Code DigestPrivalegeBitVector 8字节 Privilege Bit字段。该矢量表示该应用程序可以调用什么函数
OpcodeOpcOsdAllowTransferContainerFmtSignedContainer该容器用来授权一个程序来将一个AppContainer传递给该计算机上的另一个应用程序。在该容器的数据部分具有以下的字段。
字段 长度说明CallersAppCodeDigest 20字节 调用程序的ACDRecipientsAppCodeDigest 20字节 接收程序的ACDOpcode没有OpcOsdAllowTransfer 没有FmtSignedContainer这不是一个容器而是许多由服务器的Private Signing Key加密的字节。它们并不被保存在任何一种类型的容器中。当使用BIOSRegisterOSD()函数向BIOS注册它本身时,这些字节由操作系统驱动程序使用。
字段长度 说明NstartOffset4字节调用代码的起始偏移量NendOffset 4字节调用代码的结束偏移量CodeDigest 20字节 操作系统驱动程序的Code Digest现在将讨论用于AppContainers的Opcodes。AppContainers是只能由专门的应用程序读或/写的受保护的容器。这些容器识别密封它们的程序,并可能允许另一个程序开封一个容器,因此它们也能用作内部过程通信的保密形式。如检测病毒改变、软件许可以及安全钱包等的高级安全功能能建立在AppContainers的顶部。通常,通过使用用于加密的主密钥的派生密钥将AppContainers赋给一个指定的计算机。
操作码OpcMKKey FmtAppContainer该容器保存能用在MKContainer操作中的密钥。在创建PubKContainer过程中,通常由OsdPubKcontainerSeal()返回该容器。MKContainer操作要求该容器。
操作码OpcInitialAppContainFromServer 容器FmtAppContainer该容器是空的,而且被用作一个模块用于使应用程序来创建其它AppContainers。其中唯一有意义的字段是加密的AppCodeDigest。在这种情况下,密封器代码摘要字段为空。用来密封该AppContainers的CustomerSecret的所有位均为零。
操作码OpcCustomAppContainerData容器FmtAppContainer
该容器保存从客户到服务器的紧急应答。它保存服务器紧急的随机数字(Rs)。该容器用来响应具有OpcChallengeRequestFromServer的MKContainer。
字段 长度说明Rs16字节由服务器提供的128位随机值。或者当用作登记时的确认时,为KID‖MK现在将讨论用于PubKContainer的操作码。
PubKContainer是由客户(OSD)用一个RSA公共密钥(来自于通信密钥对)进行密封的数字信封,而且只能由接收器(通常是设备管理机构服务器)用匹配的公开密钥读取。这些在登记过程中使用,并用来在客户和验证的设备管理机构服务器之间建立一个加密通道。容器内的数据是用通常由操作系统驱动程序生成的128位RC6密码密钥(也称为产品内的主密钥)加密的。RC6密钥(主密钥)以及客户的密钥ID(KID)是用接收器的公开密钥(服务器的通信PubKey)加密的。
操作码OpcSMKEnrollRequestOuter 容器FmtPubKContainer该容器在登记过程中使用。
操作码OpcWDLNewConnection 容器FmtPubKContainer该容器由客户应用程序使用以建立一个新的加密通道。该容器的第一部分可能被再使用以避免RSA操作。在内部的MKContainer的数据部分中具有以下字段。
字段长度说明MK 16字节 128位新的随机连接主密钥现在将讨论用于MKContainers的操作码。MKContainer被用作基于这个容器的读和写程序都知晓的主密钥(由客户创建以及在PubKContainer内发送)的数据信封的一部分。当主密钥通过PubKContainer发送给服务器以后,这些能被用于在客户和设备管理机构服务器之间的保密通信。它们也能用来在保护客户机上的本地数据。
操作码OpcSMKEnrollRequestInner 容器FmtMKContainer该容器用在登记过程中。在容器的数据部分具有以下的字段。
字段长度说明SMKClientSeed 20字节 用来产生主密钥的籽数操作码OpcSMKEnrollResponse容器FmtMKContainer该容器用在登记过程中。在容器的数据部分具有以下的字段。
字段长度 说明SMKServerSeed 26字节从服务器返回的籽数,用来产生主密钥操作码OpcClientToServerWrite 容器FmtMKContainer该容器由一些客户应用程序使用以将数据发送给服务器(也就是由客户所写的数据)。
字段长度 说明Data0-64000字节 客户特定的数据操作码OpcServerToServerWrite 容器FmtMKContainer该容器由某些客户应用程序使用以接收来自于服务器的数据(也就是由服务器写的数据)字段长度 说明Data0-64000字节 客户特定的数据操作码OpcChallengeRequestFromServer 容器FmtMKContainer该容器由服务器发送,用来建立服务器系统的验证。对容器的应答是在OpcChallengeRequestFromClient中。
字段 长度 说明Rs16字节 由服务器提供的128位随机值可能为新的应用程序定义其它的操作码。使用系统应用程序接口的应用程序可能必须遵守和使用由设备管理机构提供给它们的操作码。
下面将描述一个AppContainer的格式和用来创建它的算法。首先描述开封的格式,然后描述密封和开封的步骤。
一旦程序具有一个AppContainer,它就能创建该容器的副本,然后用不同的信息填充这些副本。然而,获得第一个AppContainer的唯一的方法是使设备管理机构服务器在这个特定的计算机上为该专用程序创建一个。这涉及到AppCodeDigest。
AppContainer用来存储一个被称为主密钥的对称密钥。然后将该容器传递给执行请求一个主密钥的密封/开封操作的函数。AppContainer也能用来存储专用于应用程序的信息,该应用程序专用于一个在登记过程中由SharedMasterKey识别的指定的计算机。在每一个服务器只有解密它们自己的AppContainer的一对一的基础上,该应用程序与许多的服务器共享信息。
一个开封的AppContainer具有以下的格式。密封容器中所涉及的步骤将21-36个字节的信息添加到结尾(MAC和Padding),因此调用程序必须保证缓冲器足以保存比较大的密封的格式,否则密封操作将返回一个错误。SealerscodeDigest以及Initialization Vector(IV)都由密封操作填充。InitializationVector是一个用在密码块环链中的一个随机数。在CBC中,在用密钥加密前,IV首先与plaintext中的第一块异或操作。从由设备管理机构提供的原始的AppContainer中提取AppCodeDigest。AppContainer结构如表1所示。
密封AppContainer。加密是由主密钥、AppCodeDigest以及CustomerSecret(在大多数的时间,所有的128缺省值为0)的派生完成的。
操作系统驱动密封。通过BIOS,该操作准备将被密封的数据。它要求一个已经由设备管理机构提供的原始AppContainer。该原始的AppContainer包含使用主密钥进行加密的该特定的客户系统的一个加密的AppCodedigest。
确认该设备具有一个有效的保密主密钥。如果没有返回错误,确认该长度小到可以接受。这是以AppCodeDigest开始并包含它、以Data字段结尾并包含它的容器的长度。确认Format与FmtAppContainer一样,将Initialization Vector设置成由操作系统驱动程序安全模块传递的随机值。将SealerscodeDigest设置成由基于调用程序的验证信息的操作系统驱动程序安全模块计算的值,其中该调用程序的验证信息在OsdRegisterApplication( )过程中提供。在操作系统驱动程序AppContainer密封过程中的结构改变如表2所示。
BIOS AppContainer密封是数据密封前的最后阶段。
使DecrytedCodeDigest=Dec160Bits(AppCodeDigest)。容器内的AppCodeDigest不能由密封操作改变。这允许应用程序基于由设备管理机构提供的原始AppContainer创建一个新的AppContainer。
确认DecryptedCodeDigest等于由操作系统驱动程序安全模块确定的CallerCodeDigest。
使Key=CustomerAppKey(AppKey(SMK,AppCodeDigest),CustomerSecret),其中CustomerSecret是由操作系统驱动程序传递的值。
使Payload=Opcode‖Format‖Length‖AppCodeDigest‖IV‖SealersCodeDigest‖Data。
设置Mac=HMAC(NewKey(Key,UsageAppMac),Payload)。
将Padding设置为1-16字节的矢量以使变量和plaintext(见下文)成为16字节长的倍数。每一个padding字节具有一个等于矢量中padding字节数量的值。
使Plaintext=IV‖SealersCodeDigest‖Data‖Mac‖Padding。
使Ciphertext=Enc(Key,UseageAppenc,Plaintext)。注意Ciphertext的长度与plaintext的长度一样。
在AppCodeDigest后,用Ciphertext覆盖所有的字段。也就是说,用Ciphertext的字节替换组成plaintext的所有字节。
将Length设置成plaintext中的字节数+20(对AppCodeDigest来说)。
在SMIAppContainer密封过程中的结构改变如表3所示。在BIOS已经密封了密封的AppContainer结构后,它具有如表4所示的格式。
现在讨论开封AppContainer。操作系统驱动程序开封操作将由BIOS请求的信息收集起来以到开封容器。这提供确认小到可以接收的长度(获得正确的值字节或更少)来完成。这是包括Mac和Padding、确认格式等于FmtAppContainer、并基于在OsdRegisterApplication( )过程中提供的调用程序的验证信息计算CallersCodeDigest的长度得容器的长度。
BIOS开封操作用以开封数据。BIOS开封操作执行下面的步骤。
确认设备具有一个有效的主密钥。如果没有,则返回错误。
使DecryptedCodeDigest=Dec160Bits(AppCodeDigest)。容器中的AppCodeDigest不能由开封操作来改变。
确认DecryptedCodeDigest等于由操作系统驱动安全模块确定的CallersCodeDigest值。
使Key=CustomerAppKey(AppKey(SMK,AppCodeDigest),CustomerSecret),其中CustomerSecret是由操作系统驱动程序传递的值。
使Ciphertext=在AppCodeDigest达到Length后的数据-20字节。
使Plaintext=Dec(Key,UsageAppEnc,Ciphertext)。
用Plaintext字节替换Ciphertext字节以揭示开封的字段。
使Length=Length-20-Padding的长度。
使Payload=Opcode‖Format‖Length‖AppCodeDigest‖IV‖SealersCodeDigest‖Data。
使ExpectedMac=HMAC(NewKey(Key,UsageAppMac),Payload)。
确认Mac等于ExpectedMac。
现在将讨论MKContainer的格式和用来创建它的算法。首先描述开封的格式,然后描述密封和开封它的步骤。当它们用PubKContainer建立了一个公用的主密钥后,MKContainer最初被用来保护大(达到64K)的在客户和服务器之间发送的信息块。
MKContainer主要用来加密数据。加密是基于一个对称密钥进行的。该密钥来源于一个主密钥。使用一个来自于主密钥的对称密钥,MKContainer能被用来加密大的数据块(达到64K)。特殊情况使用是在登记过程中加密客户和服务器之间的数据传输以允许建立保密主密钥,以及加密某些客户应用程序和设备管理机构服务器之间的数据传输。
现在将讨论开封的MKContainer结构。MKContainer与Appcontainer非常相似。主要的区别在于AppCodeDigest是用已建立的Master Key的摘要替换的。对由服务器创建的MKContainer来说,SealedCodeDigest将为0。就在客户端创建的容器来说,SealedCodeDigest识别密封该容器的程序。
在MKContainer上的加密程序是由操作系统驱动模块而不是SMI模块完成的。操作系统驱动程序可能使用SMI模块来密封和开封主密钥,但所有的加密和完整性校检是由OSD代码完成的。
开封的MKContainer具有以下的格式。在开封容器中涉及的步骤将21-36个字节的信息增加到结尾(Mac和Padding),因此调用程序必须保证缓冲器足够大以保存比较大的密封的格式,否则密封操作将返回一个错误。MKDigest、SealerscodeDigest以及IV都由密封操作填充。表1示出了MKContainer结构。
所做的加密是用在AppContainer(当调用OSDPubKContainerSeal( )时创建)中传递的Master Key的派生来密封MKContainer。
密封OSD MKContainer所要求的步骤如下。这些步骤就地在缓冲器上操作,并因此覆盖开封的plaintext数据。注意Usage值对由客户所密封的容器和服务器来说是不同的,如在有关Usage值的段中所解释得那样。
密封操作要求能使用具有主密钥的AppContainer。密封步骤如下。
确认Length是可接受的。由于操作是由操作系统驱动程序执行,因此应比AppContainer大。这是以MKDigest字段开始并包含它、以Data字段结尾并包含它的容器的长度。
确认Format等于FmtMKContainer。
将MKDigest值设置为保存MK的开封的AppContainer中的内容的SHA1。
将IV设置为由操作系统驱动安全模块传递的随机值。
将SealersCodeDigest设置为由操作系统驱动安全模块确定的值。
使Key=由操作系统驱动安全模块传递的Master Key。
使Payload=Opcode‖Format‖Length‖MKDigest‖IV‖SealersCodeDigest‖Data。
设置Mac=HMAC(NewKey(Key,UsageAppMac),Payload)。
将Padding设置为1-16字节的矢量以使变量和plaintext(见下文)成为16字节长的倍数。每一个padding字节具有一个等于矢量中padding字节数量的值。
使Plaintext=IV‖SealersCodeDigest‖Data‖Mac‖Padding。
使Ciphertext=Enc(Key,Usage MKEnc,Plaintext)。注意Ciphertext的长度与plaintext的长度一样。
在MKDigest后,用Ciphertext覆盖所有的字段。也就是说,用Ciphertext的字节替换组成plaintext的所有字节。
将Length设置成plaintext中的字节数+20(对MKDigest来说)。
在OSD MKContainer密封过程中的结构改变如表2所示。
密封的MKContainer的结构如表3所示。
开封MKContainer包括操作系统驱动开封。
开封MKContainer所要求的步骤如下。错误应将容器置0。开封操作要求使用具有一个Master Key的AppContainer。开封步骤如下。
确认Length是可接受的。这是包括Mac和Padding的容器的长度。
确认Format等于FmtMKContainer。
确认MKDigest等于由操作系统驱动安全模块传递的值。
使Key=由操作系统驱动安全模块通过AppContainer传递的Master Key。
使Ciphertext=在MKDigest达到Length后的数据-20字节。
使Plaintext=Dec(Key,Usage MKEnc,Ciphertext)。
用Plaintext字节替换Ciphertext字节以揭示开封的字段。
使Length=Length-20-Padding的长度。
使Payload=Opcode‖Format‖Length‖MKDigest‖IV‖SealersCodeDigest‖Data。
使ExpectedMac=HMAC(NewKey(Key,UsageMKMac),Payload)。
确认Mac等于ExpectedMac。
现在讨论SignedContainer的格式和用来处理它的算法。首先描述开封的格式然后描述密封和开封它的步骤。这些容器最初用来将验证的信息从服务器发送到客户。例如,这些容器被用来授权一个程序调用操作系统驱动安全模块的某些函数。它们也能被用来发送文件名称的清单和每一个文件所期望的SHA1摘要(例如,以确认所下载的数据是真实的)。无论何时客户需要知道某一信息或命令的确来自设备管理机构服务器时,都能使用它们。
使用SignedContainer来证实下载的数据是真实的、证实数据的确来自设备管理机构服务器以及为向操作系统驱动程序登记的应用程序保存验证信息。表4显示了SignedContainer结构。
现在讨论密封SignedContainer。加密是用Server Signing Private Key完成的。密封SignedContainer所要求的步骤如下。这些步骤就地在缓冲器上操作,并因此覆盖开封的plaintext数据。在公开的实施例中,设备管理机构服务器执行这些步骤来密封SignedContainer。
确认选定的私有密钥是公知的。如果不是,则返回错误。
确认长度是可接受的。在密封前,长度包括PublicKeyDigest和Data。
确认Format等于FmtSignedContainer。
将PublicKeyDigest设置为匹配选定的私有密钥的公开密钥的SHA1摘要。
使Payload=Opcode‖Format‖Length‖PublicKeyDigest‖IV‖SealersCodeDigest‖Data。注意这里包括开封的长度。
使ExpectedDigest=SHA1(Payload)。
设置SigRSABlock=108 Zero字节‖ExpectedDigest
在SigRSABlock上执行PKCS#1版本2签名填充。这与PKCS#1版本1签名填充一样。该填充在Digest值的前面增加了一个固定顺序的字节以表明ExpectedDigest值是SHA1操作的结果。它也用0xFF字节替换了大多数的零填充字节。
用选定的私有密钥加密SigRSABlock。
设置Length=Length+128以便容纳SigRSABlock的大小。
在服务器已经密封了SignedContainer结构后,它具有如表5所示的格式。
现在讨论开封SignedContainer。开封SignedContainer容器所要求的步骤如下。用户执行这些步骤来验证在这种类型的容器上的签名。
确认选定的公开密钥对SMI程序来说是公知的。如果不是,返回错误。确认该Length是可接受的。在开封前,长度包括PublicKeyDigest、Data和SigRSABlock。确认Format等于FmtSignedcontainer。调用BIOS以用选定的公开密钥解密SigRSABlock。确认PKCS#1填充对使用SHA1摘要函数的签名来说是正确的。使ExpectedDigest=解密的SigRSABlock的最后20个字节。设置Length=Length-128来除去SigRSABlock的大小。使Payload=Opcode‖Format‖Length‖PublicKeyDigest‖Data。这包括开封的长度。使Digest=SHAl(Payload)。确认Digest等于ExpectedDigest。
至于BIOS开封,BIOS并不在容器它本身上工作。仅调用它来解密SigRSABlock。
现在讨论PubKContainer的格式和用来创建它的算法。首先描述开封格式,然后描述密封和开封它的步骤。这些容器最初用来在客户和设备管理机构服务器之间建立安全通信通道。PubKContainer的第二部分是包括4字节头部的完整的MKContainer对象。PubKContainer的第一部分包括生成的主密钥(MK)和客户Key ID(如果没有分配主密钥则为0)的值,而且这两个值都用接收程序的公开密钥加密。
认真选择PubKContainer的格式以允许在不改变第一部分的情况下改变该容器的第二部分。这允许客户和服务器去实现某些有意义的性能改进。OSD密封函数将返回包封在AppContainer中的生成的主密钥。在每次开始一个与服务器的新的连接(例如,存取一个新的下载)时,客户能存储和再使用该MK和PubKContainer的第一部分,而且第二部分将成为一个包含了一个新的用于加密对话的主密钥的MKContainer。这避免了需要执行一个具有SMI程序的公开密钥操作并获得了解只有真实的服务器才能知道该新的对话密钥的保密利益,因为只有真实的服务器才知道所保存的主密钥(需要解密该新的对话密钥)或知道私有密钥以读取第一部分。对服务器来说重要的最佳化是存储从PubKContainer的第一部分中抽取的主密钥并由第一部分的散列索引存储值。当再次使用PubKContainer的第一部分时,这种存储避免了需要执行私有密钥操作。因为客户总是发送整个的第一部分,因此服务器能随时刷新存储入口,然后服务器总是使用它的私有密钥(服务器通信私有密钥Communication PrivateKey)来抽取主密钥。这也意味着对在客户和服务器之间初始化信息来说只有一种格式,而不是两种独立的格式来处理再利用或创建主密钥。
在登记过程中使用PubKContainer在客户和服务器之间建立通信以便允许建立保密主密钥,以及在某些客户应用程序和设备管理机构服务器之间建立通信。
开封的PubKContainer具有如表10所示的格式。密封容器中所涉及的步骤将21-36个字节信息增加到结尾(Mac和Padding),因此调用程序必须保证缓冲器足够大以保存比较大的密封格式,否则密封操作将返回一个错误。SealerscodeDigest以及Initialization Vector(IV)都由密封操作填充。
现在讨论密封PubKContainer。加密操作是用由操作系统驱动程序在不工作时创建的主密钥的派生以及服务器的通信公开密钥完成的。
操作系统驱动密封涉及对BIOS层的两个调用。第一个是使MKContainer使用OsdMKContaierSeal()、然后BIOSRawRSAPublic( )以加密正好用在MKContainer密封操作中的MK。密封这个容器所需的步骤如下。这些步骤就地在缓冲器上操作并因此覆盖开封的plaintext数据。如在有关Usage值的节中的所解释的那样,该Usage值对由客户和服务器密封的容器来说是不同的。
确认选定的公开密钥对SMI程序来说是公知的。如果不是返回错误。确认长度是可接受的。在密封前,长度包括第一部分和开封的第二部分。在密封后,它包括通过密封第二部分增加的额外数据。确认Format等于FmtSignedContainer。使用由操作系统驱动安全模块传递的MK以及对有关MKContainer描述的步骤密封第二部分。
当第一次产生PubKContainer时,主密钥将由操作系统驱动程序随机产生。返回在该主密钥上的一个句柄给操作系统驱动程序的调用程序,因此它可能被重新使用。增大Length字段来包含由第上一步骤所增加的Mac和Padding。将PublicKeyDigest设置成选定的公开密钥的SHA1摘要。设置PubKRSABlock的Opcode和Format部分来匹配头部值。在执行这些步骤之前,数据块的剩余部分由OSD程序填充。使用一个由操作系统驱动模块选择的随机的OAEP籽数值来执行PubKRSABlock的OAEP填充。调用BIOSRawRSAPublic用选定的密钥执行RSA操作。在操作系统驱动程序已经密封了PubKContainer结构以后,它具有如表11所示的格式。
现在讨论开封PubKContainer。在本发明公开的实施例中,设备管理机构服务器执行开封。服务器的应答将会是以在MK容器的格式。客户使用MK容器操作来开封服务器应答。
现在讨论服务器开封。开封PubKContainer容器所需的步骤如下。错误则将容器置0。
确认长度是可接受的。该长度包括包含密封的MKContainer的第一和第二部分。确认Format等于FmtPubContainer。确认PublicKeyDigest对应于匹配选定的私有密钥的公开密钥。用选定的私有密钥在PubKRSABlock上执行最初的RSA解密操作。删除OAEP填充,并确认OAEP冗余是正确的(也就是说,数据块在传输中没有改变)。这使Opcode、Format、KID以及K对调用程序来说是可见的。确认Format是FmtPubKContainer。调用程序将检验能否接受Opcode。使Key等于来自于解密的PubKRSABlock的MK。使用对有关MKContainer进行描述的步骤来开封MKContainer。
现在讨论加密的原始和公开值。
派生密钥包括可能是同一函数的AppKey()、NewKey()以及CustomerAppKey()XxxKey(128位的缓冲器,如果数据低于160位,具有高单位0的160位缓冲器)。
AppKey(Key,CodeDigest)=TruncateTo128bit(SHA-1(Key‖CodeDigest))用于保护AppContainers的密钥是通过使用拥有这个容器的应用程序的代码的160位摘要从保密主密钥中得到的。产生的密钥是128位长(对大多数加密算法来说,128位更通用)。散列Key‖CodeDigest的理由是允许非根的设备管理机构服务器创建自己的AppContainer,而不需要让他们知道真实的主密钥。知道真实的保密主密钥将损害所有其它的AppContainers。
NewKey(Key,Usage)=TruncateTo128bit(SHA-1(Key‖Usage))其中Usage参数是一个32位值。散列和截尾用来简化代码,因为在NewKey( )中不必暴露产生的密钥。NewKey( )有时也取AppKey( )的结果作为自变量。
CustomerAppKey(Key,CustomerSecret)=TruncateTo 128bit(SHA-1(Key CustomerSecret))其中,CustomerSecret是一个128位值。该函数用来为包括CustomerSecret部分的AppContainers生成密钥。
AppCodeDigest=Enc160Bits(SMK,DecryptedCodeDigest)以及DecryptedCodeDigest=Dec160Bits(SMK,AppCodeDigest)均用来使用保密主密钥加密和解密160位摘要值,而且是请求设备管理机构服务器为特定设备上的专用程序创建第一AppContainer的机构的至关紧要的部分。服务器执行Enc160bits函数,而客户计算机执行Dec160Bits函数。
Enc160bits函数执行以下步骤。将DecryptedCodeDigest拷贝到AppCodeDigest缓冲器中。使Key=NewKey(SMK,UsageAppcodeDigest)。使Plaintext1=AppCodeDigest的前16字节。这是DecryptedCodeDigest的前16字节。使Ciphertext1=RC6CBCEncrypt(Key,Plaintext1)。因为plaintext只有一个数据块长,因此这与ECB模式等效。
用Ciphertext1替换AppCodeDigest的前16字节。使Plaintext2=AppCodeDigest的最后的16字节。该值的前12字节是Ciphertext1的后12字节,且该值的后4字节是DecryptedCodeDigest的后4字节。使Ciphertext2=RC6CBCEncrypt(Key,Plaintext2)。因为plaintext只有一个数据块长,因此这与ECB模式等效。用Ciphertext2替换AppCodeDigest的后16字节。
Dec160Bits函数执行以下步骤。将AppCodeDigest拷贝到DecryptedCodeDigest缓冲器中。使Key=NewKey(SMK,UsageAppcodeDigest)。使Ciphertext2=DecryptedCodeDigest的后16字节。这是AppCodeDigest的后16字节。使Plaintext2=RC6CBCDecrypt(Key,Ciphertext2)。因为plaintext只有一个数据块长,因此这与ECB模式等效。用Plaintext2替换DecryptedCodeDigest的后16字节。现在DecryptedCodeDigest的后4字节有它们的正确值。使Ciphertext1=DecryptedCodeDigest的前16字节。这包括AppcodeDigest的前4字节和Plaintex2的前12字节。使Plaintext1=RC6CBCDecrypt(Key,Ciphertext1)。由于ciphertext仅有一个数据块长,所以这与ECB模式等效。用Plaintext1替换DecryptedCodeDigest的前16字节。
Enc(Key,Usage,Message)=RC6CBCEncrypt(NewKey(Key,Usage),Message)Dec(Key,Usage,Message)=RC6CBCDecrypt(NewKey(Key,Usage),Message)其中用于密码块链模式(CBC)的初始化变量是16字节的零,且Usage值是32位长。密码块链是一个在加密前将先前的ciphertext块和当前的plaintext块结合的块加密模式。Key是128位或288位长。消息参数指定数据块石16字节长的倍数。RC6密码是于1998年8月20日由Ronald L.Rivest,M.J.B.Robshaw,R.Sidney以及Y.L.Yin在“The RC6TMBlock Cipher”中定义的,且CBC模式是于1995年在New York,NY由Bruce Schneier、John Wiley & Sons在“Applied Cryptography Second Edition”中定义的。
RC6专门设计用来满足NIST AES(Advanced Encryption Standard高级加密标准)的要求。RC6包括对各种长度密钥大小的支持,并被进行优化以利用自RC5以来在CPU方面的进步。
当与大多数容器一起使用这种原语时,Message从一个16字节的随机值(被称为IV)开始,并在结尾填充1至16个字节来使Message成为密码的块大小(16字节)的倍数。注意16字节的IV并不用在传统的CBC模式中,因为它不是直接地与随后的plaintext块异操作。相反,在加密过程中,它与0(什么也不做)异或操作,然后用密钥加密来生成ciphertext的第一数据块。第一ciphertext数据块然后在加密该数据块前进行与下一plaintext数据块的异或操作。在解密过程中,解密第一数据块以及与零异或操作来生成是原始的随机的IV数据块。解密第二ciphertext块并与ciphertext的第一数据块异或操作来生成plaintext的第二数据块。
用于Enc和Dec的填充是许多其值等于填充的字节数的相同的字节。例如,如果增加两个填充的字节,则每一个字节具有值0x02。通常至少有一个填充的字节,因此如果plaintext已经是16字节的倍数长,那么增加填充的16字节,而且那些字节中的每一个都具有值0x10。宗教的战争挑战随机对抗可预见的填充字节的优点。这种设计要求可预见的填充字节。注意很容易通过检查加密数据的最后字节确定增加了多少填充。
HMAC(Key,Message)原语。基于任何加密摘要函数的Hugo’s MessageAuthentication Code(HMAC)调用基本完整的原语。在本发明中,它基于由NIST&NSA在1995年4月17日在“Secure Hash Standard”中定义的SHA-1。发表的有关HMAC原语的论文表明它具有极好的安全特征以在摘要函数中弥补潜在的缺点。SHA-1是由美国商业部为一个用于计算消息或数据文件的压缩表达式的安全散列算法采用的一个标准规格。当输入长度<264位的任何消息时,SHA-1生成一个调用消息摘要的160位输出。然后信息摘要能被输入到为信息生成或验证签名的数字签名算法(Digital Signature Algorithm,DSA)中。HMAC(Key,Message)=SHA-1(Key xor Opad‖SHA-1(Key xor Ipad‖Message))。
Opad及Ipad值是不同的512位长的常量,以匹配SHA-1的内部压缩函数的数据块大小。在该设计中Key必须小于512位长。Opad及Ipad值连同HMAC的详细内容是由H.Krawczyk、M.Bellare以及R.Canetti在“HMACKeyed-Hashing for Message Authentication”中定义的。与消息的直接摘要相比,HMAC原语要求两个以上的SHA1压缩函数的迭代。这样支付极好的保密特征的开销很低。
HMAC是用于使用加密散列函数的信息验证的机制。HMAC能与任何迭代的加密散列函数如MD5、SHA-1以及一个保密共享密钥一起使用。HMAC的加密强度依赖于下面的散列函数的特性。
RSA操作使用从RSA许可的代码在BIOS中执行。
Ciphertext=RSAOaepEncrypt(PublicKey,OaepSeed,Message)Message=RSAOaepDecrypt(PrivateKey,Ciphertext)这些原语使用RSA算法执行加密和解密。就加密原语来说,使用正如由RSALaboratories在“PKCS#1 v2.0RSA Cryptography Standard”中所定义的OAEP(最佳的不对称的加密填充,optimal asymmetric encryption padding)首先填充Message,然后根据PublicKey取幂和降低模数。OAEP所要求的随机籽数值作为一个参数传递给这个函数。就解密原语来说,根据PrivateKey,在ciphertext被取幂和降低模数后,验证和删除OAEP填充。在大多数情况下,Message是128位密钥和160位SMK KID的连接。
设计PKCS用于二进制和ASCII数据;PKCS也与ITU-T X.509标准兼容。所公布的标准是PKCS#1、#3、#5、#7、#8、#9、#10、#11和#12。PKCS#13和#14当前正在开发。PKCS包括专门算法和独立算法的实现标准。支持许多的算法,包括RSA以及Diffie-Hellman密钥交换,然而,只有后两种特别地详细。PKCS也为数字签名、数字信封、扩展的证书定义一个独立算法语法;这使某些人实现任何加密算法无论如何都要符合一个标准的语法,并因此获得互操作性。详细描述PKCS标准的文献可在RSA Data Security’sFTP服务器(可从http∥www.rsa.com或通过无名的ftp到ftp.rsa.com、或通过发送e-mail到pkcs@rsa.com)上获得。
下面是公开密钥加密标准(Public-Key Cryptography Standards,PKCS)PKCS#1定义了用于通过使用RSA公开密钥加密系统来加密和标记数据的机制。
PKCS#3定义了一个Diffie-Hellman密钥一致性协议。
PKCS#5描述了用于用口令导出的一个保密密钥加密一个字符串的方法。
PKCS#6正逐步停止采用以支持X.509版本3。
PKCS#7为包括加密增强如数据签名和加密的消息定义了一个总的语法。
PKCS#8描述了用于私有密钥信息的格式。该信息包括一个用于某些公开密钥算法的私有密钥,以及可选的一组属性。
PKCS#9定义了为用在其它的PKCS标准中的选定的属性字节。
PKCS#10描述了用于证书请求的语法。
PKCS#11为加密设备如智能卡和PCMCIA卡定义了一个技术独立的可编程接口,被称为Cryptoki。
PKCS#12指定了一个用于存储或传送一个用户的私有密钥、证书、其它的保密等的便携格式。
PKCS#13使用Elliptic Curve Cryptography定义了用于加密和标记数据的机制。
PKCS#14为伪随机数生成提供了一个标准。
使用RSA算法,SigBlock=RSASigEncrypt(PrivateKey,Digest)以及Digest=RSASigDecrypt(PublicKey,SigBlock)原语执行加密和解密。就加密原语来说,使用正如由RSA Laboratories在“PKCS#1 v2.0RSA CryptographyStandard”中所定义的签名填充来首先填充160位的SHA-1摘要值,然后根据PublicKey取幂和降低模数。就解密原语来说,根据PrivateKey,在对ciphertext取幂和降低模数后,验证和删除该填充。该填充将摘要算法的标识符进行编码,且这些原语只支持SHA1算法。这些原语是创建和验证数字签名的过程的一部分。其它的步骤包括计算或验证已被标记的真实的SHA1摘要。
AppCodeDigest是用来识别拥有一个容器的应用程序的数据。它不适用于所有的容器。该数据是基于调用加密函数的代码产生的。该数据通常由设备管理机构生成、加密和标记。时常在运行时间由BIOS将解密的AppCodeDigest(ACD)与CallerCodeDigest进行比较。属于服务器的CodeDigest经常为0。
SealerCodeDigest/CallerCodeDigest是在函数中基于函数的调用程序计算的数据。用来计算这个摘要的信息在诸如向BIOS注册、向操作系统驱动程序注册等注册期间在用OpaacOsdAuthorization作为容器操作码的SingedContainer中提供的。
登记是客户系统经历的较早一阶段。在该阶段,在客户系统和设备管理机构服务器之间创建和交换主密钥。该步骤包括PubKContainers。当登记过程没有分配该主密钥时,主密钥用一个临时的随机值代替直到用正确的主密钥代替它为止。
BIOS和操作系统驱动程序(OSD)都参与容器操作。与密封有关的容器函数包括OSDAppContainerSeal()、OSDMKContainerSeal()、OSDPubKContainerSeal()以及BIOSAppContainerSeal()。
OSDPubKContainerSeal()函数创建一个随机的对话密钥(Master Key)并将它返回到包含在AppContainer中的调用程序。然后使用该AppContainer调用其它的MKContainer()操作。图 示出了一个典型的PubKContainer算法。
涉及开封的容器函数包括OSDAppContainerUnseal()、OSDMKContainerUnseal()、OSDSignedContainerUnseal()、OSDPubKContainerUnseal()、以及BIOSAppContainerUnseal()现在讨论容器分类执行细节。这些分类包括PubKContainer和MKContainer。
下面对PubKContainer的格式和在密封和开封中使用的类中的方法的描述。这些容器最初用来在客户和设备管理机构服务器之间建立一个安全通信通道。PubKContainer的第二部分是一个包括4字节头的完整的MKContainer对象。PubKContainer的第一部分包括所生成的主密钥(MK)和客户的Key ID(KID)值(如果没有分配主密钥则为0),且这两个值均是用接收程序的公开密钥进行加密的。
仔细选择PubKContainer的格式以允许在不改变容器的第一部分的情况下改变容器的第二部分。这允许客户和服务器去实现某些有意义的性能改进。OSD密封函数将返回包封在AppContainer中的生成的主密钥。在每次开始一个与服务器的新的连接(例如,存取一个新的下载)时,客户能存储和再使用该MasterKey和PubKContainer的第一部分,且第二部分将成为一个包含一个新的用于加密对话的主密钥(Master Key)的MKContainer。这避免了需要用SMI程序执行一个公开密钥操作,并获得了解只有真实的服务器才能知道该新的对话密钥的保密利益,因为只有真实的服务器知道所保存的主密钥(需要解密该新的对话密钥)或知道私有密钥以读取第一部分。对服务器来说重要的最佳化是存储从PubKContainer的第一部分抽取的Master Key,并用第一部分的散列索引存储值。当再次使用PubKContainer的第一部分时,这种存储避免了需要执行私有密钥操作。注意因为客户总是发送整个的第一部分,因此服务器能随时刷新存储入口,因此服务器总是使用它的私有密钥(服务器通信私有密钥)来抽取Master Key。这也意味着对在客户和服务器之间初始化信息来说只有一种格式,而不是两种独立的格式来处理再利用或创建Master Key。
在登记过程中使用PubKContainer在客户和服务器之间建立传送以便允许建立保密主密钥,以及在某些客户应用程序和设备管理机构服务器之间建立传送。表6示出了最后密封的PubKContainer结构。
与PubKContainer有关的构造程序和方法如下所述。
Public PubKContainer()是一个空的初始化记录器对象的容器。至于publicPubKContainer(InputStream in),用输入数据流初始化容器,然后将输入数据流读入到一个字节数组中。然后使用parseBuffer方法分析缓冲器。也初始化记录器对象。
Public PubKcontainer(byte[]buf)。
容器用字节数组初始化,然后将它作为一个字节数组读入到缓冲器中。然后使用parseBuffer方法分析缓冲器。也初始化记录器对象。Private void seal()废弃RsaLibException。下面用来密封PubKContaineropcode、KID、MK、PubKDigest、Sealed MKContainer。使Format为3=FmtPubKConatiner。用opcode、format、reserved、KID和MK构造PubKBlock。Opcode、KID和主密钥是由调用程序设置的。调用JNI包封程序用于一个试验数据块中的RSA库和RsaOaeEncrypt(PubKDigest,PubKBlock)以构造加密的PubKRSABlock。设置length等于密封的MKContainer(MkC)的长度+148(128-PubKRSABlock,20-PubKDigest)。该长度表示来自包括密封的MkContainer的PubKDigest的字节和。构造密封的PubKContainer与Opcode‖Format‖Reserved‖Length‖PubDigest‖PubKRSABlock‖sealedMKc一样的字节数组。使用来自安全公用类的addArray方法来构造链接数组。
Private void unseal()废弃RsaLibException、ContainerException。
检验invalidOpcode、invalidFormat和invalidLen是否为false,并废弃ContainerException。如果它们中任何一个不是所期望的那样,则在parseBuffer中将它们设置成false。
通过解密,获得PubKBlock,它是Opcode‖Format‖Reserved‖MK‖KID。
通过用于RSA库的JNI包封程序,具有rsaOaeDecrypt(PubKDigest,PubKBlock)的PubKRSABlock。
在PubKBlock、操作码、格式、KID和主密钥上执行有效性和长度检验。
Private void parseBuffer(byte[]buffer)是一个帮助函数来分析引入的存储在为缓冲器中的密封容器,其中该缓冲器为Opcode‖Format‖Reserved‖Length‖PubDigest‖PubKRSABlock‖sealedMKc的。
如果不是所期望的那样,则设置invalidOpcode、invalidFormat和invalidLen。Public byte[]getRawFor()废弃containerException。
检验数据和MKDigest非空并调用密封方法。
返回在如Opcode‖Format‖Reserved‖Length‖PubDigest‖PubKRSABlock‖sealedMKc的密封操作中建立的缓冲器。
Public byte getOpcode()返回容器的操作码。
Pubic byte[]getPubKDigest()从容器返回PubKDigest。
Public byte[]getKID()从容器返回KID,如果需要则开封。
Public byte[]getMK()废弃ContainerException
从容器返回MK,如果需要则开封。
Public MKContainer getMKContainer()废弃ContainerException-抽取密封的嵌入在由parseBuffer完成的Pubk中的MK容器,开封Pubk部分以获得MK,并为MK容器设置它。
Public void setOpcode(byte opcode)废弃ContainerException-在检验它是否在有效范围中之后,为容器分配操作码。
Public void setPubKDigest(byte[]digest)废弃ContainerException-如果传递为空或者长度不等于20,则废弃exception,设置PubKDigest。
Public void setKID(byte[]Kid)废弃ContainerException-如果传递为空或者长度不等于20,则废弃exception,设置Key ID。
Public void setMK(byte[]Mk)废弃ContainerException-如果传递为空或者长度不等于20,则废弃exception,设置MK。
Public void setMKContainer(byte[]Mkc)废弃ContainerException-设置将被嵌入在PubKContainer中的密封的MKContainer。
Private void log(int aWarningLevel,String message)-将作为一个参数传递过来的该WarningLevel与当前值进行比较,以及如果很紧急就输出它。
下面是涉及MKContainer的构造程序和方法。
现在讨论MKContainer的格式和用来创建它的算法。首先描述开封格式然后描述密封和开封它的步骤。在使用PubKContainer已经建立了一个公有的Master Key以后,MKContainer最初被用来保护在客户和服务器之间传送的信息的大组块(达到64K)。
MKContainer主要用来加密数据。加密是基于一个对称的密钥进行加密的。该密钥来源于Master Key。通过使用来源于Master Key的一个对称密钥,MKContainer被用来加密大的(达到64k)数据块。在登记过程中,特殊情况使用是加密在客户和服务器之间的传输以便允许建立保密主密钥,并加密某些客户应用程序和设备管理机构服务器之间的传输。最后密封的结构如表13所示。
Public MKContainer()是空的正好初始化记录器对象的容器。
Public MkContainer(InputStream in)-用输入数据流初始化容器,然后将它作为字节数组读入到Buffer中。然后使用parseBuffer方法分析缓冲器。也初始化记录器对象。
Public MkContainer(byte[]buf)-用字节数组初始化容器,然后将它作为字节数组读入到Buffer中。然后使用parseBuffer方法分析缓冲器。也初始化记录器对象。
Private void seal()废弃RsaLibException下面是用于密封MKContainer,调用在这些操作码、MKDigest、数据上的设置方法。
设置Format为3=FmtPubKContainer设置scd为20个0的字节数组将长度设为数据长度+56(20-MKDigest+16-iv+20-scd)将长度转换成2字节数组从随机数字生成器中取iv为16字节数据,调用cryptoPrimitivesgenerateRandomNumber(16)方法使用安全实用程序的addToArray方法构造payload为Opcode‖Format‖Reserved‖Length‖MKDigest‖iv‖scd‖data。
将newKey设为NkeyForSealing=CryptoPrimitive.newKey(MKDigest,ctnrConstants.UsageMKMacServer);然后从cryptoPrimitive调用获得MacMac=CryptoPrimitive.getHmac(NkeyForSealing,payload);构造Plaintext为iv‖scd‖data‖mac将Padding设置成1-16字节的矢量以使variable、Plaintext(见下文)成为16字节的倍数长。每一个填充字节具有一个等于矢量中填充的数量的值。这是用adjustPad方法在SecurityUtils类中完成的。
为Plaintext增加填充,现在Plaintext是iv‖SealersCodeDigest‖Data‖Mac‖Padding使Ciphertext=Enc(Key,UsageMKEnc,Plaintext)。Ciphertext的长度与Plaintext的长度一样。
在Plaintext+20中设置Length为字节的数量。在2字节的数组中存储该值。
构造一个密封的MKContainer作为一个具有Opcode‖Format‖Reserved‖Length‖MKDigest‖Ciphertext的缓冲器
private void unseal()废弃RsalibException、ContainerException。检验invalidOpcode、invalidFormat或者invalidLen是否为false,并废弃ContainerException。如果它们中任何一个不是所期望的,则在parseBuffer中把这些设置成false。从parseBuffer中抽取的Ciphertext传递给CryptoPnmitivedec,获得界面plaintext的解密方法.dec方法被称为dec.(MKDigest,ctnrConstants,UsageMKEncServer,ciphertext)。
从plaintext的最后字节可以知道填充字节以及它指定了增加多少填充字节。填充字节是从plaintext中删除的,数据大小是通过删除mac长度以及从plaintext的长度中减去填充字节计算的。
计算iv、scd以及data的长度并存储在一个2字节的数组中。由于计算data的长度,且iv、scd以及mac的长度是预定的,因此它们都是从plaintext中抽取的。
修改Length=Length-20-Padding的长度构造payload为Opcode‖Format‖Reserved‖Length‖MKDigest‖iv‖scd‖data。构造newKey为NkeyForSealing=CryptoPrimitive.newKeyMKDigest,ctnrConstants.UsageMKMacServer);然后从cryptoPrimitive调用获得ExpectedMac为ExpectedMac=CryptoPrimitive.getHmac(NkeyForSealing,payload);如果mac和ExpectedMac不相等,废弃ContainerException。
Private void parseBuffer(byte[]buffer)是一个帮助函数以分析引入的存储在缓冲器中的密封容器,这些缓冲器是Opcode‖Format‖Reserved‖Length‖MKDigest‖CipheredText在加密格式中,密文组成‖iv‖SealersCodeDigest‖data如果不是所期望的,则设置invalidOpcode、invalidFormat、invalidLen publicbyte[]getRawForNet()废弃ContainerException,检验Key ID、MK以及密封的MKC(MkBuff)是否是空,然后调用密封方法。返回在密封操作中建立的缓冲器如Opcode‖Format‖Length‖MKDigest‖IV‖SealerCodeDigest‖Date‖mac‖padpublic byte getOpcode()-返回容器的操作码Pubic byte[]getMKDigest()废弃ContainerException-从容器返回MKDigest。
Public byte[]getData()废弃ContainerException-从容器返回data,如果需要则开封。
Public byte[]getMK()废弃ContainerException-从容器返回MK。
Public void setOpcode(byte Opcode)废弃ContainerException-在检验它是否在有效范围中之后,为容器分配操作码。
Public void setMKDigest(byte[]digest)废弃ContainerException-如果传递为空或者长度不等于20,则废弃exception,设置MKDigest。
Public void setData(byte[]Kid)废弃ContainerException-如果传递为空,则废弃exception,设置DataPublic void setMK(byte[]Mk)废弃ContainerException-如果传递为空或者长度不等于16,则废弃exception,设置MK。
Private void log(int aWarningLevel,String message)-将作为一个参数传递过来的该WarningLevel与当前值进行比较,以及如果很紧急就输出它。
现在讨论OSD软件。操作系统驱动程序(OSD)是系统10的核心组件中的一个。它是被动态地装入到该系统中的一个内核模式。它的上部边界为安全应用程序提供安全服务。它的下部边界与安全BIOS进行接口,提供了低级安全功能。操作系统驱动程序提供的服务包括RSA和RC6加密函数、应用程序完整性检验以及随机数生成。
软件操作环境使用如WDM Windows设备驱动程序的操作系统驱动程序。该设备驱动程序也可运行在Window98、Windows Me、Windows2000和未来的Microsfot Windows操作系统下。
现在讨论操作的原理并略述OSD操作的过程。图2示出了客户组件层。
现在讨论初始化。在应用程序调用OSD函数前,通过调用OsdRegisterApplication函数,用操作系统驱动程序注册它自己本身。操作系统驱动程序做下面的操作以注册一个应用程序。获得应用程序识别信息,如ProcessID。
在作为参数传递的SignedContainer中基于密钥摘要获得公开密钥索引。操作系统驱动程序在初始化过程中创建的密钥表将密钥摘要映射成密钥索引。调用BIOSRawRSAPublic以开封在Signed Container中的数据块。该数据块包含地址范围、所期望的代码摘要和PrivilegeBitVector和完整性检验的频率。
基于地址范围创建调用程序的部分的代码摘要。应这样执行应用程序以使所有的OSD函数调用非常接近,被称为OSD服务调用块(SIB)。OSD服务调用块必须(在法律上要求)是不普通的,从而防止其它的应用程序为了自己的目的进入SIB和使用OSD的API。该SIB是增加了专用于该调用应用程序的APIs的一组值。
将创建的代码摘要和所期望的代码摘要进行比较。如果它们相同,则验证该应用程序否则返回错误。如果该应用程序被验证,则在注册的应用程序表中增加一个入口。入口包括应用程序的识别信息(Process ID)、OSD服务调用块的地址范围、OSD服务调用块的代码摘要和PrivilegeBitVector以及完整性检验频率。
现在讨论服务调用。在一个应用程序向用操作系统驱动程序注册后,该应用程序请求OSD服务。在每一次调用它的函数时,操作系统驱动程序要完成下面的工作。
检验应用程序的完整性。从注册的应用程序表中,基于完整性检验频率进行。通过创建应用程序的OSD服务调用块的代码摘要,操作系统驱动程序完成它。然后和所期望的代码摘要进行比较。如果它们相同,则应用程序完整性为OK,否则返回error。
检验Privilege Bit Vector以观察应用程序是否具有调用该函数的权力。继续执行OSD代码以服务于该请求。操作系统驱动程序可能依赖于所请求的服务调用安全BIOS程序。调用OsdRandomAddNoise函数。这将增加PRNG的不可预见性。
现在讨论应用程序的取消注册。在适当在终止应用程序前,它调用OsdUnregisterApplication用操作系统驱动程序取消注册它它本身。OSD驱动程序删除在注册应用程序表中的应用程序的入口。
下面详细描述操作系统驱动程序(OSD)的功能。操作系统驱动程序是能在Window98、Windows Me以及Windows2000下运行的WDM内核模式驱动程序。WDM是基于Windows NT层的32位设备驱动模型,具有对PNP和PowerManagement的额外支持。因为操作系统驱动程序并不管理所有的物理设备,不分配任何硬件资源。操作系统驱动程序实现作为一个模块来执行。没有类/小类驱动程序对。当在系统中装入操作系统驱动程序时,创建一个FunctionalDevice Object(FDO)。图3示出了操作系统驱动程序组件的相互作用。
现在讨论注册的应用程序表创建。操作系统驱动程序保存注册的应用程序的一个表。基于应用程序的检验频率从注册的应用程序表中,操作系统驱动程序周期性地检验调用程序的完整性。它获得调用程序的OSD服务调用块的地址范围,并创建代码摘要。然后再检验来自于注册的应用程序表的所期望的代码摘要。
现在讨论RSA加密函数。操作系统驱动程序执行接口函数以完成PubKContainer密封登记,其中PubKContainer是在BIOS、AppContainer密封/开封以及SignedContainer开封中创建的。然而,所有的RSA公开/私有密钥算法是在安全BIOS中执行的。操作系统驱动程序调用BIOS程序以完成容器操作。
操作系统驱动程序实现RC6算法函数以密封/开封MKContainer。除了在登记过程中这是在操作系统驱动程序本身而不是在BIOS中完成的,BIOS执行MKContainer处理以保护该主密钥。
现在讨论OSD接口和APIs。
该节描述操作系统驱动程序与系统内核和完全BIOS的接口。该节也定义了OSD API函数,用户模式的应用程序能调用它以获得OSD安全服务。这里也描述操作系统驱动程序应执行的内部函数。
操作系统驱动程序函数的上边界接口如下。在WDM模型下,系统I/O管理器通过创建一个I/O Request Packet(IRP)和将它向下发送给设备驱动程序来对设备驱动器提出一个I/O请求。能通过发送DEVICE_IO_CONTROL IRP调用OSD安全服务。用于Device_IO_Control的每一个句柄程序提供了一个特定的功能。在以下定义操作系统驱动程序IO_CONTROL代码。
IOCTL_OSD_REGISTER_APPLICATION。句柄程序向操作系统驱动程序注册应用程序,并调用BIOS程序。
IOCTL_OSD_UNREGISTER_APPLICATION。句柄程序向操作系统驱动程序未注册应用程序。
IOCTL_OSD_GET_PUBLIC_KEY。句柄程序使用密钥索引作为参数从BIOS提取公开密钥,并调用BIOS程序。
IOCTL_OSD_VERIFY_SIGNED_DIGEST。句柄程序验证一个数据块的RAS数字签名。需要调用BIOS程序。
IOCTL_OSD_RANDOM_GENERATE。句柄使用PRNG来生成一个随机数字。依赖于PRNG执行,该句柄可能或不可能调用的BIOS程序。
IOCTL_OSD_PUBK_CONTAINER_SEAL。句柄使用用密钥索引指定的公开密钥加密在容器中的数据块并调用BIOS程序。
IOCTL_OSD_SIGNED_CONTAINER_UNSEAL。句柄程序验证容器是否真的由验证服务器标记和调用BIOS程序。
IOCTL_OSD_APP_CONTAINER_SEAL。句柄程序用从主密钥导出的密钥密封AppContainer并调用BIOS程序。
IOCTL_OSD_APP_CONTAINER_UNSEAL。句柄程序用从主密钥导出的密钥开封AppContainer并调用BIOS程序。
IOCTL_OSD_APP_CONTAINER_TRANSFER。句柄程序密封AppContainer,而该AppContainer只能由运行在同一个平台或不同平台的另一个程序开封。调用BIOS程序来开封包括验证信息的SignedContainer。
IOCTL_OSD_MK_CONTAINER_SEAL。句柄程序用主密钥密封容器。真正的密封是在操作系统驱动程序内部完成。调用BIOS程序来开封AppContainer以获得该主密钥。
IOCTL_OSD_MK_CONTAINER_UNSEAL。句柄程序用主密钥开封容器。开封是在操作系统驱动程序内部完成的。AppContainer调用BIOS程序来获得该主密钥。
IOCTL_OSD_ENROLL_GENERATE_REQUEST。句柄程序调用BIOS程序来生成伪的SMK、消息密钥和SMK客户籽数。
IOCTL_OSD_ENROLL_PROCESS_RESPONSE。句柄程序调用BIOS程序来生成用于该平台的主密钥。
IOCTL_OSD_INVALIDATE_SMK。句柄程序调用BIOS函数来使由先前的登记中生成的主密钥无效。
IOCTL_OSD_SET_PUBLIC_KEY。句柄函数在BIOS密钥表中安装额外的RSA公开密钥。
现在讨论操作系统驱动程序的低边界接口。在操作系统驱动程序的低边界接口上,操作系统驱动程序调用安全BIOS接口程序来获得由低级BIOS提供的安全服务。安全BIOS接口是在基于32位目录服务接口的基础上实现的。当将操作系统驱动程序装入系统时,它需要搜索安全BIOS入口点。在每一个程序调用前,操作系统驱动程序需要基于安全BIOS规格建立注册环境。
现在讨论User Mode API函数。执行User Mode API库。通过调用在该库中的函数,保密应用程序能访问由操作系统驱动程序提供的保密服务。API函数如下所述。
Int OsdRegisterApplication(IN unsigned char*pAuthorizationBuffer,IN unsigned int*pAuthorizationBufferLength)该函数用OSD代码注册应用程序。它检验该应用程序是否被验证了,并在OSD保持的注册的应用程序表中保存应用程序信息。只有从注册应用程序内的一个单元或从其它的OSD函数调用它们,其它的OSD调用才能作用。如果注册是成功的,则返回0。否则返回error。PAuthorizationBuffer和pAuthorizationBufferLength参数指定由设备管理机构服务器创建的SignedContainer的单元和长度。
该函数使用IOCTL_OSD_REGISTER_APPLICATION来调用OSD服务。
Int OsdGetCapabilities(OUT unsigned short*pVersion,OUT unsigned short*pCapabilities)该函数返回OSD版本号以及OSD CR性能和系统状态。
版本号定义如下。
第一字节 第二字节次版本主版本性能WORD被定义成具有15位。位0表示系统已经成功登记。1,成功;0,失败。位1表示登记类型。0,离线登记;1,在线登记,以及位2-15是预留的。
该函数使用IOCTL_OSD_GET_CAPABILITIES来调用OSD服务。
Int OsdUnregisterApplication()函数通过从登记的应用程序表中删除调用程序的入口来取消登记该调用程序。该函数使用IOCTL_OSD_UNREGISTER_APPLICATION来调用OSD服务。
Int OsdGetPublicKey(IN int nKeyIndex,OUT unsigned char*pModulusBuffer,IN/OUT unsigned int*pModulusBufferLengthOUT unsigned int*pExponent)如果成功提取存储在密钥表的nKeyIndex行中的RSA公开密钥,则该函数返回0。在特定的缓冲器中返回公开密钥的模(1024位数字),且公开密钥的指数(3或65537)被放在由pExponent识别的单元中。由pModulusBufferLength识别的单元最初被设为实际使用的字节的数量。返回的非0值表示错误。首先将密钥的模拷贝到具有Most Significant Byte(MSB)的缓冲器中。就从闪速ROM中载入的密钥来说,NkeyIndex值起始于零并顺序地增加。在运行了OS以后,通过WDL的OSD Security Module,负的nKeyIndex值引用被载入到SMM公开密钥表中的密钥。
该程序可由一个应用程序使用以定位对应于该应用程序从X.509验证中了解的公开密钥的nKeyIndex。
如果调用程序不是一个注册的应用程序或另一个OSD程序,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变过。
该函数使用IOCTL_OSD_GET_PUBLIC_KEY来调用OSD服务。
Int OsdRSAVerifySignedDigest(IN int nKeyIndex,IN unsigned char*pSignedDigestBuffer,IN unsigned int*pSignedDigestBufferLengthIN unsigned char*pDigestBufferIN unsigned int*pDigestBufferLength)该函数验证RSA数字签名。使用由nKeyIndex指定的公开密钥来抽取使用匹配的私有密钥加密的所期望的摘要值,它执行PKCS#1格式化的RSA公开密钥操作来加密由pSignedDigestBuffer和pSignedDigestBufferLength指定的数据缓冲器。将所期望的摘要与由pSignedDigestBuffer和pSignedDigestBufferLength参数指定的值进行比较。如果它们相等,则返回0,否则它返回一个非0错误代码。如果nKeyIndex无效,则程序也将返回一个错误。pSignedDigestBuffer和pSignedDigestBufferLength值能从调用OsdSHA1 Final程序中产生。
在pSignedDigestBuffer中的数据首先存储在MSB中,并且它必须正好与用于所选定的公开密钥的模一样长。
如果调用程序不是一个登记的应用程序或另一个OSD程序的话,则该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变过。
函数使用IOCTL_OSD_VERIFY_SIGNED_DIGEST来调用OSD服务。
Int OsdDigestInit(OUT DigestContext*pDidgestContext)该函数能由任何应用程序调用。它在将用来计算SHA1摘要值的调用程序的地址空间中初始化一个数据结构。
调用程序能修改该数据结构,因此OSD模块不能依赖于该结果的正确性。当这些SHA1程序由一个应用程序使用以验证签名时,该应用程序委托自己来计算正确的摘要值然后委托操作系统驱动程序(以及依次是BIOS SMI安全模块)用正确的RSA公开密钥来计算。当OSD层注册一个新的应用程序时,数据结构被保存在操作系统驱动程序存储器中,因此操作系统驱动程序能相信该结果。参见节8关于DigestContext数据结构的定义。
Int OsdDigestUpdate(IN DigestContext*pDigestContext,IN unsigned char*pBuffer,IN unsigned int*pBufferLength)该函数能由任何应用程序调用。通过向它提供由pBuffer和pBufferLength参数指定的数据字节,它使用一个调用程序地址空间中的数据结构来更新SHA1摘要对象的状态。
在调用该程序之前,对一个必须由在缓冲器中的字节的数量和填充的单元来说,PBufferLength是一个指向该单元的指针。该程序并不改变那个单元,因此长度可直接传送而不是通过引用。
然而,在该设计中所有的缓冲器长度是通过引用传递的,目的是使接口更一致。
Int OsdDigestFinal(IN DigestContext*pDigestContext,OUT unsigned char*pDigestBuffer,IN/OUT unsigned int*pDigestBufferLength)该函数可由任何应用程序调用。它使用一个在调用程序的地址空间中的数据结构来计算可能用0传递或对OsdDigestUpdate的更多调用的一个数据块的SHA1摘要的最后结果。通过追加填充和总长度(以字节为单位)以及执行最后的摘要操作,它处理保存在该数据结构的缓冲器中的任何字节。结果放在由pDigestBuffer和pDigestBufferLength参数指定的缓冲器中。在调用该函数前,pDigestBufferLength指向指定pDigestBuffer的最小尺寸的单元,以及在成功完成后,该单元被设为放在缓冲器中的字节的数量。对SHA1摘要来说,结果将为20字节长。
Int OsdRandomGenerate(OUT unsigned char*pDataBuffer,in unsigned int*pDataBufferLength)该函数使用操作系统驱动程序的伪的随机数字生成器用由pDataBufferLength参数指定的字节的数量来填充该特定数据缓冲器。
如果pDataBufferLength是20字节或更少,则执行一次下面的步骤以及将ResultBlock的前导字节复制到pDataBuffer中,其余的则丢弃。如果需要不只20字节,则根据需要重复执行下面的步骤。StateBlock和ResultBlock均为20个字节的值。StateBlock表示PRNG的全局态。
ResultBlock=SHA1(StateBlock‖StateBlock)StateBlock=StateBlock异或SHA1(StateBlock‖ResultBlock)当已经填入了pDataBuffer时,通过调用OsdRandomAddNoise结束。
如果调用程序不是一个登记的应用程序或另一个OSD程序的话,则该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变过。
函数使用IOCTL OSD RANDOM GENERATE来调用OSD服务。
Int OsdPubKContainerSeal(IN int nKeyIndex,IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength,OUT unsigned char*pMKBuffer,IN/OUT unsigned int*pMKBufferLength)该函数用来保证传送到设备管理机构服务器的数据不能被其他的客户读取。只有设备管理机构服务器才知道开封该容器的所必需的私有密钥。PcontainerBuffer参数指向一个保存了一个开封的PubKContainer结构的存储块。调用程序应填充如在有关PubKContainer的节中描述的各种字段。那个部分还描述了由这个函数执行的步骤。NkeyIndex识别应用来密封该容器的公开密钥。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。在pContainerBuffer中使用的信息描述了必须被保护的数据的长度。
PMKBuffer和pMKBufferLength参数指定一个用AppContainer填充的缓冲器。该AppContainer保护为PubKContainer生成的主密钥。该信息被用于创建具有相同主密钥的MKContainer。
通过调用OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_PUBK_CONTAINER_SEAL来调用OSD服务。
Int OsdSignedContainerUnseal(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength)该函数用来检验容器是否真的由服务器标记。如果签名无效,返回一个错误。SignedContainer的格式和由该函数执行的步骤是在有关SignedContainers的节中描述的。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述了必须保护的数据的长度。
通过调用OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_SIGNED_CONTAINER_UNSEAL来调用OSD服务。
Int OsdMKContainerSeal(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength,IN unsigned char*pMKBuffer,IN unsigned int*pMKBufferLength)该函数用来密封容器,因此它只能由知道该主密钥的其他人开封。该密钥可以是设备和服务器知道的主密钥,也可以是由客户生成的、并在一个PubKContaienr中发送给服务器的新密钥。在输入时,PcontainerBuffer参数指向一个保存一个开封的MKContainer结构的存储块。在输出时,密封容器。调用程序应填充如在有关MKContainer的节中描述的各种字段。在那个部分中也描述了由该函数执行的步骤。该函数为密钥使用使用客户常数。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述必须保护的数据的长度。
PMKBuffer和pMKBufferLength参数指定一个保存AppContainer的缓冲器。该AppContainer保护通过调用OsdPubKContainerSeal函数生成的主密钥。通过调用OsdRandomAddNoise(),程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_MK_CONTAINER_SEAL来调用OSD服务。
Int OsdMKContainerUnseal(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength,IN unsigned char*pMKBuffer,IN unsigned int*pMKBufferLength
IN int wasSealedByServer)该函数将使用给定主密钥来开封由另一个实体密封的容器。在输入时,PcontainerBuffer参数指向一个保存一个密封的MKContainer结构的存储块。在输出时,容器是开封的。参见有关MKContainer的节来了解开封格式。那节还描述了由该函数执行的步骤。如果参数wasSealedByServer为零,则由该程序使用的该密钥使用常数是客户常数,否则它们是服务器常数。有关密钥使用常数详见该节。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述了必须被保护的数据的长度。
PMKBuffer和pMKBufferLength参数指定保存AppContainer的缓冲器。该AppContainer保护通过调用OsdPubkContainerSeal函数生成的主密钥。
通过调用OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_MK_CONTAINER_UNSEAL来调用OSD服务。
Int OsdAppContainerSeal(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength)该函数将密封容器,因此它只能由运行在相同设备上的相同的程序开封。当输入时,PcontainerBuffer参数指向一个保存了一个开封的AppContainer结构的存储块。当输出时,容器密封。调用程序应填充如在有关AppContainer的节中描述的各种字段。那节也描述了由该函数执行的步骤。该函数为密钥使用而使用客户常数。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述了必须被保护的数据的长度。
通过调用OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_APP_CONTAINER_SEAL来调用OSD服务。
Int OsdAppContainerUnseal(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength,IN int wasSealedByServer)该函数将开封由运行在该计算机上的应用程序和特别用于在该计算机上的应用程序的服务器密封的容器。在输入时,PcontainerBuffer参数指向一个保存了一个密封的AppContainer结构的存储块。在输出时,容器开封的。有关开封的格式参见有关AppContainer的章节。该章节还描述由该函数执行的步骤。如果参数wasSealedByServer是0,则由该程序使用的密钥使用常数是客户常数。否则它们是服务器常数。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述了必须被保护的数据的长度。通过调用OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变。函数使用IOCTL_OSD_APP_CONTAINER_UNSEAL来调用OSD服务。
Int OsdAppContainerTransfer(IN/OUT unsigned char*pContainerBuffer,IN/OUT unsigned int*pContainerBufferLength,IN unsigned char*pAuthorizationBuffer,IN unsigned int*pAuthorizationBufferLength)该函数用来密封容器,因此它只能由运行在相同设备上的不同程序来开封。容器原来的主人失去了打开它的能力。当然,原来的主人能制作该容器的备份,并继续打开和关闭该备份,但传递后的容器将用不同的密钥加密,因此只有新的主人才能打开它。该特征能由安全键盘读取模块使用以便捕捉击键和安全地将它们传递给正确的应用程序。
当输入时,PcontainerBuffer参数指向一个保存一个开封的AppContainer结构的存储块。当输出时,密封容器。调用程序应填充如在有关AppContainer的节中描述的各种字段。那个章节还描述了由该函数执行的步骤。该函数为密钥使用而使用客户常数。该函数证实在为使用密封它之前当前拥有该容器的调用程序(检验DecryptedCodeDigest)是新的拥有者。
pAuthorizationBuffer和pAuthorizationBufferLength参数指定由设备管理机构服务器创建的SignedContainer的单元和长度。受保护的容器详见设计文献。操作码是OpcOsdAllowTransfer,并且容器内的数据指定程序的AppCodeDigest,其中该程序正调用该函数,且程序的AppCodeDigest能开封该容器。容器的SealerCodeDigest字段将识别调用该函数的程序。
当输入时,pContainerBufferLength指向含有适合该容器缓冲器的最大的字节数目的单元。当输出时,它包含用在pContainerBuffer中的实际的字节数目。用在pContainerBuffer中的信息描述了必须被保护的数据的长度。通过OsdRandomAddNoise(),该程序结束。如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变过。
Int OsdEnrollGenerateRequest(OUT unsigned char*pPubKContainerBuffer,IN/OUT unsigned int*pPubKContainerBufferLength)该函数将生成一个伪SMK、主密钥和对话密钥的客户籽数。返回一个具有主密钥和对话密钥的客户籽数的密封PuKContainer以及具有对话主密钥的密封的AppContainer。将该PubKContainer发送到设备管理机构服务器。BIOS将在SMRAM中保存客户籽数及主密钥。当输入时,pPubKContainerBuffer和pAppContainerBuffer指向缓冲器。pPubKContainerBufferLength和pAppContainerBufferLength指向具有缓冲器的长度的单元。当输出时,缓冲器将用返回的Containers填充。
如果成功,该函数返回,否则返回error。该函数使用IOCTL_OSD_ENROLL_GENERATE_REQUEST来调用OSD服务。
Int OsdEnrollProcessResponse(In unsigned char*pContainerBuffer,IN unsigned int*pContainerBufferLength,OUT unsigned char*pAppContainerBuffer,
IN/OUT unsigned int*pAppContainerBufferLength,OUT unsigned char*pPubKContainerBuffer,IN/OUT unsigned int pPubKContainerBufferLength)该函数调用SMI程序来生成主密钥并将它保存在SMRAM中。该程序将创建一个具有Key ID(SMK的散列)和其它数据的Sealed AppContainer。
当输入时,pContainerBuffer指向一个缓冲器,该缓冲器存储由设备管理机构服务器在在线登记过程中返回的MKContainer或者在离线登记过程中具有伪服务器籽数的SignedContainer。当输出时,pAppContainerBuffer存储含有Key ID的密封的AppContainer。在离线登记过程中,PpubKContainerBuffer指向包含服务器籽数和客户籽数的缓冲器。在在线登记过程中,该指针可以是NULL。
该函数使用IOCTL_OSD_ENROLL_PROCESS_RESPONSE来调用OSD服务。
Int OsdInvalidateSMK()该函数使由先前的登记过程生成的主密钥无效。该函数使用IOCTL_OSD_INVALIDATE_SMK来调用OSD服务。
Int OsdSetPublicKey(IN unsigned int nKeyIndex,IN unsigned char*pKeyBuffer,IN unsigned int*pKeyBufferLength)该函数或者替换由nKeyIndex指定的RSA公开密钥、或在BIOS密钥表中增加一个新密钥。在输入时,nKeyIndex指定该密钥替换或增加。PkeyBuffer指向密钥缓冲器。pKeyBufferLength表示该缓冲器长度。
现在讨论内部函数。下面的函数由OSD驱动程序在内部调用。它们并不对用户应用程序公开。
Int OsdInitialize(void)该函数初始化操作系统驱动程序的状态。在将它装入该系统后,操作系统驱动程序调用该函数。该函数向BOIS层注册并初始化PRNG。PRNG是通过清零StateBlock、从信号量文件读保存的平均信息量、将它转换成二进制以及将它传递给OsdRandomAddSeed函数来进行初始化。如果没有保存的平均信息量,则操作系统驱动程序执行收集平均信息量字节的慢处理、调用OsdRandomAddSeed然后使用OsdRandomSaveEntroy来将平均信息量保存到信号量文件中。
Int OsdRandomAddNoice(void)在每一个WDL的OSD安全程序的结尾调用该函数。通过增加对攻击者来说有点不可预见的全程信息,它帮助增加了全程的PRNG的不可预见性。
用新的上下文调用OsdDigestInit。
调用OsdDigestUpdate传递StateBlock对每一个快速平均信息量源来说调用OsdDigestUpdate传递该快速平均信息量值(32位或64位值)在处理完最后一个快速平均信息量源后,调用OsdDigestFinal生成ResultBlockStateBlock=StateBlock异或ResultBlock该快速平均信息量包括CPU周期计数、如超高速缓存失误合计的CPU统计以及所有的系统时钟位。新的StateBlock是旧的数据块和摘要值的异或的结果。通过用异或将旧数据块和新数据块混合,我们保证新状态的不可预见性低于旧状态(假定用于该摘要函数的普通特性)。相反,等式StateBlock=SHA1(StateBlock)将导致减少不可预见性的数量,因为SHA1象导致两个输入值映射到相同的输出值的随机函数一样动作。有更少可能的具有每一个迭代的输出。
如果主板或CPU支持一个硬件RNG,那么应该包括该硬件值。只有增加可快速使用的随机性的数量。
如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变过。
Int OsdRandomAddSeed(IN unsigned char*pDataBuffer,IN unsigned int*pDataBufferLength)该函数更新操作系统驱动程序的PRNG的状态。它执行以下步骤。
StateBlock=StateBlock异或SHA1(StateBlockpD a taBuffer)这就是说,初始化一个SHA1上下文,并用StateBlock和在指定的缓冲器的字节更新它。
调用OsdRandomAddNoise()如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将验证调用程序的代码的SHA1摘要自从登记以来没有改变。
Int OsdRandomSaveEntropy()该函数将来自于操作系统驱动程序的全程PRNG的信息保存到Semaphore文件的一个字段中。它并不保存原始的StateBlock,因为它将导致操作系统驱动程序重新使用相同的随机字节序列。相反,它保存从当前(160位)状态产生的32字节(256位)值。从那个值重新启动PRNG将不会导致它重新产生相同的字节。基本的步骤如下调用请求一个32位随机字节的缓冲器的OsdRandomGenerate将这些二进制字节编码成64位十进制ASCII字符在Semaphore文件的一个字段中保存这些字符调用OsdRandomAddNoise()如果调用程序不是一个登记的应用程序或另一个OSD程序的话,该函数返回一个错误。定期地,该函数将检验调用程序的代码的SHA1摘要自从登记以来没有改变。
现在讨论数据格式。下面是对在本发明中使用的数据结构和格式的描述。
Authorization Buffer是一个SignedContainer。在该容器中的Data块在表14中定义。Register Applicatoin Table的入口在表15中定义。该表可以实现作为一个链表。
下面的问题是由本发明提出的。一个问题是如何从操作系统驱动程序读取应用程序代码。只要核心的模式OSD象顶级驱动程序一样且在PASSIVE_LEVEL中运行,它就能读取User Mode地址空间。
另一个问题是如何获得调用程序的入口点。当一个应用程序调用DeviceIOControl系统函数时,它能从ring3转换到ring0。以及对不同的ring,该硬件执行不同的堆栈。操作系统驱动程序需要追溯到用户模式堆栈以获得入口点。这依赖于DeviceIOControl的执行,也就是它有多少栈帧(函数调用)。下面的四种可能方法是可行的(1)模拟指令,举例来说,通过异常。(2)直接从User模式而不是通过驱动程序调用BIOS程序。(3)建立INT门,建立一个中断句柄。所有的函数将由软件中断来调用。(4)验证和执行在OSD空间中的用户代码。该方法将具有如Win32 API一样的相同的问题。
下面是对在MFCA VPN产品中的应用程序注册模块(ARM)组件的描述。该应用程序登记模块辅助Strong Authentication Module(SAM)以提供对安全AppContainers的访问,其中在客户设备和能加密的服务器之间交换该AppContainers。
应用程序注册模块负责为能访问如VPN的服务器应用程序的客户设备提供AppContainer Keys。该应用程序注册模块通过一条如SSL的安全通信通道与SAM通信。
图4是说明多因子客户验证登记的框图。图4示出了各种模块是如何与应用程序注册模块相互作用的。
SAM和应用程序注册模块具有一个客户/服务器联系。该应用程序注册模块是一个将对不同企业的SAM公开许多服务的Internet服务器。它的目的是在特定设备向特定企业的登记过程中,帮助客户和SAM。最终的结果是提供具有合适的App Key的SAM以密封和开封正在注册的设备中的容器。该操作只能为每一个设备/企业组合执行一次。
以下面的次序调用组件。SSL连接检验程序校验合法的SAM通过一个SSL连接与应用程序注册模块对话。应该重新检测与应用程序注册模块的连接的其它所有格式。AppContainer Key提供程序将使用所接收的pubKContainer来首先在这些企业上执行校检,然后,准备最终将返回给SAM的AppContainerKey。
指向应用程序注册模块的入口点,包括指定URL,如AppContainerKeyRequest。
Http//arms.DeviceAuthority.com/arm/AppContainerKeyRequest,例如,在它的体内URL具有由客户系统产生的PubKContainer()以及由SAM提供的某些特殊信息的一个URL。
现在将讨论用于ClientCert处理/验证/授权的操作原理。配置应用程序注册模块web服务器mod_ssl来了解设备管理机构RootCA证书。Mod_ssl校验当前的SAM.ClientCertificate具有一个导致设备管理机构的验证路径。RootCA。例如SAM.ClientCertificate由SubscriptionManager.CA.cert发布,该SubscriptionManager.CA.cert由设备管理机构Root CA证书发布。被构造在mod_ssl中的最后一个证书将成功地终止SAM.ClientCert的校检。
在验证路径的校验过程中,mod_ssl将考虑已经被配置的CertificateRevocation List(CRL)。每一次Subscription Manager取消一个SAM时,将不得不考虑更新CRL(举例来说,购买SAM的企业将停止)。Subscription Manager将具有一个存储它的CRL的URL。该URL存储在SAM.Clientcert内部。应用程序登记模块将定期地从该URL获得该文件。
验证是由设备管理机构RootCA提供的,而Subscription Manager.CAaSAM.ClientCert是由通过构造SAM的证书提供的。如果我们使用Versign作为RootCA,将不会是这种情况。
验证是由设备管理机构RootCA、Subscription Manager.CA以及SubscriptionManager.CR1的组合提供的如果它具有一个SAM.ClientCert且它不在Subscription Manager.CertificateRevocationList,则验证SAM以联系应用程序注册模块。
SSL连接验证程序。这是从小服务程序调用的Java类。它向小服务程序提供一个API以确认指定的连接的验证信息。当它存储有关SSL连接的信息时,小服务程序将把它传递给至少一个请求对象。使用那个信息,SslConnectionVerifer将确定所连接的客户是否是先前注册的那一个。
连接验证程序记录任何失败的尝试。为调试目的,记录成功的尝试。验证程序返回一个提供有关正在连接的客户的信息的对象。验证服务程序也从请求中攫取有效的任何用户名信息。这由ClientCert管理人员小服务程序使用。
输入是Servlet Request Object如果用户名/口令被用来构成该请求,则它存储SSL客户证书信息以及有关用户的信息。输出是SslConnectionVerifier对象具有如IsSslOK()、GetCertInfo()、IsUserAuthenticate()和GetUserInfo()的方法。该SslConnectionVerifier访问x509 Client Certificate的所有字段。
AppContainerKey Provider小服务程序为应用程序注册模块分发密钥。它是ARM模块的主要入口点。它调用SslConnectionVerifier。从它的输入流,它接收存储有关发送客户设备的pubkc()的SAM的信息的pubkc()。该SAM信息有一个与SslConnectionVerifier对象了解的信息一致的enterprise字段。调用Enforcer,将所有来自于SslVerifier的信息和来自于pubkc()的信息传递给它。基于Enforcer的结果,然后该小服务程序从加密机请求一个AppContainerKey。在pubkc()中的Key ID+ACD将被传递给该加密机。通过SSL连接,将AppContainerKey返回给SAM。
输入是具有存储一个Key ID的pubkc()、企业信息以及ACD的输出流(InputStream)(来自于小服务程序API)。请求对象(来自小服务程序API)存储有关当前连接的信息(SSL,......)。输出在输出流(Output Stream)(来自小服务程序API)上返回一个AppContainerKey、并在数据库中修改使用的许可的数量。
Subscription Manager收集Strong Authentication Module(SAM)所要求的信息以管理许可。这些许可控制可由SAM从在MFCA产品中的ApplicationRegistration Module(ARM)请求的AppContainersKeys的数量。应用程序注册模块负责为已经被激活可访问VPN的客户设备提供AppContainer Key。
被允许将许可证出售给购买SAMS的公司的销售人员,通常使用到Subscription Manager的Web用户接口。该接口收集将由应用程序注册模块使用的有关公司、许可证号、有效期、销售人员ID以及SAM标识符(ClientCertificate Signing Request)的信息以确定哪个SAM请求一个AppContainerKey。
签名管理程序生成一个SAM将载入和验证的防止窜改(带标记和/或加密)的文件。该文件包括签名信息(即允许使用的许可证号,SAM的容许的地址......)除Subscription Information File(SIF)外,签名管理程序也返回带标记的SAM的标识符。
对许可信息和用户证书的数据库来说,签名管理程序是一个前端处理程序。Web用户接口使用用户证书验证许可零售商。它要求以下有关公司的信息,零售商正获得用于包括公司名称、公司联系信息、许可证号、许可有效期(从开始日期到结束日期)、SAM(将SubScription File赋值给该SAM)的IP或MAC地址、SAM的Client Certificate Request(CRS)以及Reseller标识符的许可。
签名管理程序生成被安全地转送到安装SAM的人员的以下项目带标记的Client Certificate、以及防止窜改的Subscription Information File(SIF)。具有由SIF Singing Utility(SSU)标记的SIF将完成防止窜改。
Subscription Manager将在内部用以下的信息更新数据库取消SAM的ClientCertification所要求的信息、有关SAM的信息(许可证号、有效期、用于许可证更新的联系信息......)、以及有关购买SAM的公司的信息,它可能公司拥有的唯一SAM。
签名管理程序的操作原理如下。首先在一个零售商/通道合伙人和一个设备管理机构之间建立一份契约。然后在设备管理机构由某人使用License-reseller信息编辑器/浏览器来创建一个将被授权的最初的Reseller/Channel-partner帐户以出售许可给SAMs。
这产生一个与零售商/通道合伙人取得通信的用户/口令。该零售商/通道合伙人安排在某一公司安装SAM。他进入SAM信息编辑器/浏览器,并输入公司信息和许可信息。
公司完成安装SAM公司已经分配了一个IP地址给SAM,并已经生成了一个Client Certificate Signing Request。该信息被传递给零售商。然后该零售商(或者具有OTP的公司)返回到SAM信息编辑器/浏览器,并输入SAM和CSR的IP地址。
服务器生成未标记的SIF,并将它发送给SIF Signing Utility。SSU立即返回该带标记的SIF。该SAM的CSR变为由充当代表Root设备管理机构的中间CA的Subscription Manager标记的真实的Client Cert。
没有OTP,零售商将SIF和Client Certification传递给公司。然后该公司将SIF安装到SAM知道的目录。Cert安装到他们的SSL模块中。现在公司准备请求AppContainerKeys。
现在详细讨论模块组件。SSL连接验证程序是一个从小服务程序调用的java类。它为小服务程序提供一个API以确认给定连接的验证信息。当它存储有有关SSL连接的信息时,小服务程序将它传递给至少一个请求对象。
使用该信息,SslConnectionVerifier确定所连接的客户是否以前注册过。可能这种验证将被限定到校验连接超过SSL以及客户有证书。这种简化是因为有多少Apache+mod_ssl将被配置他们只接收来自于具有已知证书的客户。
该连接验证程序记录所有失败的尝试。为跟踪目的,记录成功的尝试。该验证返回一个提供了有关正在连接的客户(零售商的计算机)的信息的对象。该验证程序也攫取来自于请求的任何有效的用户名信息。这将用来检验真实的授权的零售商正在使用他的计算机而不是某一计算机。
该输入是Servlet Request Obiect,如果使用用户名/口令来产生请求,则该Servlet Request Object存储SSL客户证书信息和有关用户的信息。该输出是一个Sslconnection Verifier对象具有象IsSslOK()、GetCertInfo()、IsUserAuthenticated()和GetUserInfo()一样的方法。
SAM信息编辑器/浏览器模块允许添加/编辑/删除等许可信息。例如,它允许生成有关每一个公司、每一个SAM IP/MAC地址、每一个将期满的许可的报告。用有效的零售商信息(用户名/口令、客户证书)验证所有的操作。
SIF生成器模块生成一个Subscription Information File。将所生成的SIF发送给SIF Signing Utility(SSU)。该SSU将使用私有密钥来标记文件,与该私有密钥匹配的公开密钥与SAM软件一起发送。这是唯一一个SIF标记的密钥对。
SIF是一个人们可读的文件。在支持过程中,允许IT部门全体人员立即访问联系信息、及时间、IP地址等。SIF包括公司名称、公司联系信息、用于有效许可的联系、许可证号、许可有效期(从开始日期到结束日期)、零售商标识符、SAM的IP或MAC地址(将Subscription File赋给SAM)。
Certificate Signing Request(CSR)句柄模块负责创建X509兼容的用Root设备管理机构的密钥标记的Certificates。如果已经提交请求的零售商是正确地验证过的(用户名/口令和客户证书已验证),那么它只标记证书。它要求SAM信息、相应的CSR以及联系信息以提醒SAM的客户证书的有效期。CSR在某一字段中包含计算机IP地址。因此SAM安装者负责用在某一字段中的IP地址生成一个客户证书。
输出是可用在SAM计算机上的X509客户证书。Openssl是在SAM和签名管理程序上处理证书事件的基础工具。该模块也处理已公布的SAM.ClientCertificates的撤消。该撤消信息将被放入一个Certificate RevocationList(CRL)中。该列表能用Opensll进行处理。通过在该服务器上的HTTP,该CRL文件对任何人下载都是有效的。
许可期满检测程序定期地扫描许可数据库,并给在签名过程中提供的联系发送email。SAM证书期满检测程序定期地扫描所生成的SAM客户证书的数据库,并给在CSR过程中提供的联系发送eamil。
License-Reseller信息编辑器/浏览器向该系统注册零售商,并向他们提供用于他们的浏览器的Client Certificate、或仅仅是用户名和口令或这两者。它也允许跟踪在销售过程中零售商执行得有多好。
SIF Signing Utility(SSU)为设备管理机构提供了一个简单的方法以便访问签名信息。在最小值,SSU标记SIF。
应用程序现在讨论Multi-Factor Client Authentication。该系统的一个应用程序是用于访问一个虚拟专用网络(VPN)的多因子客户验证应用程序(MFCA)。验证过程的第一部分是一个用户名/口令对(用户知道的东西)。第二部分将是加密启动的设备的验证,基于BIOS或使用软件(用户具有的软件)。
在一个MFCA的简单版本中,通过传统的、经过RADIUS到验证服务器的传输实现口令验证,其中该验证服务器使用一个合法的口令数据库。在首选实施例中,使用SPEKE口令验证协议增强该过程。口令验证协议在公开号为US的美国专利中公开了。在这两种情况下,MFCA为设备管理机构提供一个新的装置。
系统包括下面的软件组件。在验证VPN服务器的客户设备上运行的客户软件组件。软件必须是能加密的。
在企业受保护的网络内部,我们保护的运行在VPN的一个或更多服务器计算机上的软件组件。这将由购买VPN产品的公司的IT部门管理。
运行在连接到因特网、并访问KID/SMK对的数据库的设备管理机构服务器(可能由由管理机构而不是企业管理)上的软件组件。
讨论一个增强的VPN客户时提供一个MFCA概述。客户设备通常是向设备管理机构登记的一个Windows计算机。在登记以后,客户设备具有一个有效的主密钥。在首选实施例中,它具有固件支持,在BIOS ROM中实现了本发明的加密特征,尽管可能使用了只有软件的版本。计算机通常是由客户VPN软件的用户所拥有,其中该用户想通过VPN网关访问公司的受限网络。
用户通常通过正规的Internet服务提供器(ISP)访问Internet。在该ISP和VPN网关之间的网络不是值得信赖的,因此这两者之间的通信必须是安全的。VPN方案的首要目的是提供从客户设备到VPN网关的端到端加密安全。
MFCA客户包括由本发明实现的加密核心技术和一个与标准的VPN客户软件合作的客户应用程序以建立与服务器的安全连接。MFCA结构要求计算机在VPN登录前进行登记。在它第一次运行时,客户应用程序发现客户先前是否登记过。如果先前没有登记,则客户应用程序执行登记,而且只有该过程完成后,才会继续MFCA操作的其余部分。
Enterprise VPN网关和Strong Authentication Module(SAM)是由本发明提供的。MFCA启动的企业具有一个连接在Internet和保护的企业网络之间的VPNGateway服务器。
VPN通常包括许多相互合作的计算机以验证访问和阻塞靠不住的通信量。通常他们与防火墙协力工作。最重要的计算机是VPN网关和StrongAuthentication Module(SAM)服务器。
SAM位于共同的网络中且基本上是可信任的。在某些情况中,这意味着在VPN网关和SAM服务器之间的通信不需要加密。对这两台计算机的一个简单的安全校验是校验另一个的IP地址,在共同的网络内部所做的路由选择是可信任的。
SAM是在为一个特殊的用户和设备管理机构访问内部网方面与VPN网关相互作用的服务器软件。它访问登记过的设备的“数据库”,该设备也将被允许访问。在SAM代码和数据库之间的接口将尽可能地开放,以允许在它下面放置不同的数据库实现(例如,通过使用ODBC或LDAP)。核心应当同SAM-Database连接一起利用,该SAM-Database可能使用Secure Socket Layer(SSL)协议来实现。
SAM包含密封和开封AppContainers的代码。SAM Server也可能包含许可政策(设备有权访问网络期满、允许进入的设备号等等)的跟踪。加密函数可能在BIOS-ROM和只有软件的格式中提供。
另外,在确定设备/用户对是否应该允许访问(两因子验证的第一部分)方面,这些计算机、附加的硬件和/或软件可能Gateway和SAM合作。用在工产中的不同的标准和产品来执行该函数,包括已经访问过用户名和口令的数据库的RADIUS服务器以及用于确定基于政策的访问权力的各种系统。
SAM组件也可能被用来实施软件许可计划。该SAM组件典型地由拥有VPN的企业的IT部门而不是由其它的管理机构管理。然而,它可能与曾出售给该企业有权使用MFCA软件的其它的管理机构具有信托关系。
许可政策为企业的整个帐户或为单个的客户帐户(例如,有人可能丢失他的膝上型电脑,以及我们不得不删除该设备)考虑到期满时间。根据由系统管理部门制定的政策,SAM执行这些撤消和终止。
许可能基于将被允许访问数据库的设备的最大数量。许可函数周期性地检查和跟踪正在发生的事情。这可能涉及SAM在正常基础上将信息发送给卖主特定单元。许可管理最好是从基于远程Web的工具完成。
Application注册模块(ARM)是一个对不同企业的SAMs公开服务的Internet服务器。它的目的是在向用特定企业注册特定设备的过程中帮助用户和SAM。最终的结果是提供具有适当的App Key的SAM来密封和开封正在注册的设备内的容器。
在被称为“MFCA Registration”的过程中,对每一个设备/企业联合,只需要执行该操作一次。该应用程序注册模块服务器包含一些前端服务器—估计可能但并不是必不可少的、Web Server(s)-与存储信息的后端数据库通信,其中该信息说明了那时用于不同公司的有效许可、他们所期望的证书是什么等等。
人们在此完成许可强制。为特殊的企业基本跟踪注册用户的数量就是一个例子。应用程序注册模块服务器执行许可强制和许可记录和检查,但并不跟踪单个的登录。应用程序注册模块也访问设备管理机构“Encryption Server”,该验证机构存储在登记过程中生成的KID/SMK表。基于Web的远程接口处理这些企业帐户。
作为对应用程序注册模块的增强的应用,通过Web接口(SubscriptionManager),自动进行数据输入,该接口允许零售商、通道合伙人以及IT管理人员输入适当的信息来激活SAM与中心ARM数据库协作。在下面的表中列出了调用的过程。
过程名说明MFCA Subscription 为SAM生成许可信息的过程,出售许可证的销售人员通过登录拥有称为Subscription Manager的服务器的设备管理机构来初始化签名过程。该销售人员输入有关购买SAM的公司的信息请求多少许可、SAMs Client Certificate、以及其它信息,......
该过程的输出是Subscription Information File(SIF)以及一个Client Certificate(参见Certificate)。
Enrollment 客户设备处理获得一个SMK、并能使用加密服务的过程。该过程涉及客户设备和设备管理机构Enrollment Server。
登记需要客户设备含有加密的核心函数,在BIOS或Emulation API中。
MFCA Registration 客户设备获得注册符来使用特殊企业的VPN的服务的过程。它涉及客户、SAM服务器以及一些与RAM Server的相互作用的服务器。
注册要求客户设备先前已经向设备管理机构登记过。
这种注册的最终目的是提供具有适当的App Key的SAM以便密封和开封将与客户设备交换的APPContainer。
Login 客户设备获得访问企业的内部网的过程。这是MFCA想完成的最后的服务。它涉及在客户设备和SAM Server之间的相互作用,但不要求与设备管理机构的额外的相互作用。SAM Server不得不验证作为具有VPN Gateway的两因子验证的第二阶段的客户设备。它使用App Container来执行该过程。
除上述以外,不得不配置VPN客户、SAM Server以及ARM Server以便能成功地分发适当的App Keys。
注册过程包括以下两个步骤(1)与特殊的计算机一起工作的App Key的传输,从设备管理机构到我们的公司的SAM服务器,以及(2)生成CustomerApp Key的Customer Secret的传输,从SAM服务器到客户。
App Key是如下的一个函数(1)正在注册的计算机的保密主密钥(只有设备管理机构和计算机本身知道),以及(2)应用程序的操作系统驱动程序(VPN应用程序,在本实例中)App Key是下面的加密操作的结果AppKey=trunc 128(SHA1(SMK‖ACD)).
SAM服务器生成一个附加的128位的Customer Secret,它保持来自于其它Device Authorities的秘密,并用下面的操作计算Customer App KeyCustomerAppKey=trunc128(SAH1(AppKey‖CustomerSecret)).
SAM服务器存储该值(或,可选地分别存储AppKey和CustomerSecret),并将CustomerSecret发送给客户。客户记录该秘密(尽管因为它是保密主密钥而不是一个“大秘密”)。SAM也向客户发送一个可能存储一个用于LoginCounter机构的起始值的密封的AppContainer。在一个替换实施例中,安全询问/应答机构代替了Login Counter机构。
注册过程是基于AppContainers。客户开封先前收到的AppContainer,增大注册计数、重新密封该容器,并将它发送给作为VPN Authentication Protocol一部分的VPN Gateway。SAM服务器得到该容器,打开它并将注册计数与最后记录的值进行比较,如果它在可接受的范围内,则将准许调用客户访问企业的内部网。
在注册的一个替换过程中,客户从VPN Gageway接收一个随机的询问值,开封先前所接收的该AppContainer,将Customer Secret和该询问值与一个单向函数结合(通常使用一个加密散列函数,如SHA1),以及将单向函数的结果返回给作为VPN Authentication Protocol一部分的VPN Gateway。
SAM服务器获得该结果,并将它与它自己的询问值和Customer Secret的单向函数的计算结果进行比较。如果SAM服务器的计算结果与客户的结果匹配,则VPN Gateway将准许调用客户访问公司的内部网。
MFCA的特定实现可能将特定VPN软件产品作为目标。某些VPN卖主提供允许其它公司在客户机或服务器中定制他们的产品的APIs。这些卖主也具有为已写的软件的验证程序以便与这些APIs相互作用。MFCA可能以附加格式或以具有VPN卖主产品的整体格式递送。
现在详细叙述所涉及的过程。
登记对MFCA安装来说是首要过程。客户设备必须具有核心加密系统,它包括操作系统驱动程序(OSD)、访问BIOS和硬件的低级驱动程序,而且设备必须已经登记和存储了一个有效的主密钥。
登记操作可能作为VPN软件安装的一部分来执行。也说是说,当客户第一次试图访问VPN时,如果客户设备还没有登记,它能执行登记。当他第一次开始客户应用程序时,这将作为初始化用户经验的一部分发生。不需要用户输入。
客户安装涉及用户接收的软件,该软件包含可能包括用于MFCA安装和增强的MFCA注册验证的附加代码的已存在的VPN Client的一个增强格式的MFCA VPN Client。最好,由VPN卖主的客户SDK提供的APIs应该允许MFCA代码与他们的数据库静态地链接。理论上,MFCA产品的相关部分是在所计算的ACD的范围内。
现在讨论服务器安装过程。Strong Authentication Module(SAM)配置安装用户/设备帐户。这通常由企业系统管理人员执行。SAM与VPN和/或与验证服务器结合。下面有许多可用的选项SAM可能是一个用于已存在的验证服务器的插件。在验证服务器和SAM之间的接口是一个API。SAM是一个服从某些端口、理解用户协议或RADIUS的服务器。验证服务器和SAM之间的接口是一个网络协议。
VPNs和RADIUS服务器也可高度配置,允许许多的配置。RADIUS服务器(万一它是现存的)依赖于政策、用户和口令等验证客户。
SAM负责验证设备。一个简单的实施例包括独立的RADIUS服务器,并能被用来直接与网关、或者充当代理的另一个验证服务器对话。该配置用户接口(UI)将独立于其它任何验证服务器。
VPN Gateway/RADIUS服务器配置。管理员配置一个用户名/口令对。这将是“永久的”用户注册的用户名/口令对。该过程并不涉及任何设备管理机构,并且是独立于MFCA的“通常的”单因子配置。
SAM配置。管理人员配置用户名、Application Device ID(ADID)以及Registration Password。在替换实施例中,管理人员还可能创建用户和设备之间的关联以表明有效的结合、限制用户从特定的计算机验证。
Application Device ID(ADID)是人们可读的公开名称、在每一个企业中的唯一值,但不是非得经过企业。Registration Password是由系统管理人员产生的。它必须是一个可信的随机数。
在另一个实施例中,人们可能使用Key ID作为唯一的标识符来代替ADID。然而,实际上人们并不相信通用的“唯一标识符”的观念,因此首选实施例使用一个由IT管理人员选择的独立的ADID。存储在SAM数据库中的所有的口令都是仔细考虑的。
在该结构中描述的模式暗示用户数据库和设备数据库是分开的。结果是存在于用户数据库中的任一用户将用存在于设备数据库中的任一设备进行验证。没有限制特定的用户必须与特定的计算机连接。
MFCA注册(第一连接)。用户从他企业的IT部门获得用户名/口令对和ADID/Registration Password对。用户经历如下。
用户运行一个安装应用程序。这是一般的Windows安装。如果客户没有登记,执行登记操作。安装程序提示用户向VPN输入识别该用户的数据块。用于正常登录的用户名/口令以及用于注册的ADID/Registration Password。
用户第一次连接时,VPN网关/RADIUS验证用户名/口令对,并校验允许他进入的当前政策。SAM向外部ARM服务器注册该设备,并配置它自身。如果每一项都成功,则用户在VPN中。
在接下来的登录中,用户将不再需要进入他的ADID/RegistrationPassword。Client VPN App应只提示用户输入一个用户名和口令。客户记住该ADID、AppContainer的位置、以及已经从服务器接收的用户秘密。
整个服务器相互作用流程如下。参照说明MFCA Registration的框图的附图4。
客户应用程序使用先前存在的VPN协议对VPN网关提出第一个请求。使用预先先存在的验证方法,VPN网关以具有RADIUS服务器的通常方法校验用户名和口令对。然后VPN网关确定客户需要向SAM Server注册。VPN网关将请求发送给SAM Server。
请求包含(1)公开的ADID,(2)用适应的设备管理机构服务器的Communication Public Key加密的PubK Container,该设备管理机构服务器包含企业名称/URL以及用于App的ACD(或一个识别ARM数据库中的ID)。
SAM不能解密PubK,因此它将它传递给ARM Server。这种连接必须提供SAM的某种验证给应用程序注册模块。在HTTPS实现中,将设备管理机构公布的证书提交给SAM服务器,反之亦然,其中在用设备管理机构打开帐户的过程中建立证书。
应用程序注册模块使用Communication Key的专用位打开PubKContainer,且如果需要的话就用新的设备ADID更新它的内部表。应用程序注册模块对照它的数据库校验企业以找出它是否有一个有效的许可。如果每一项都是正确的,则应用程序注册模块具有客户设备的Key ID,因此它找出保密主密钥,并为给定ACD计算Appkey。然后用一种安全方法将AppKey传回给SAM(可能使用HTTPS连接的应答)。
相对于ADID,SAM存储AppKey,构造具有AppKey的Customer AppKey和一个用于Customer Secret的新的随机值(或者SAM直接存储该CustomerAppKey而忽略AppKey),并构造原始AppContainer,在那儿存储起始的128位Login Counter(它的超始值可以是注册口令)以及企业名称/URL。
SAM密封AppContainer,并将它和Cutstomer Secret(可能经过VPNGateway)传递回客户。该AppContainer并不需要被发送给加密的客户。很明显它并不泄露任何保密。偷听者不能记录它以及将它发送给服务器以尝试和获得访问VPN,因为容器将具有一个错误的计数值。
VPN Gateway从SAM服务器接收Ok,并现在准许客户访问内部企业网。客户在众所周知的位置存储AppContainer和Customer Secret。
应用程序注册模块处理Appkeys,但我们不知道Customer Secret和LoginCounter的起始值—只有SAM知道。尽管设备管理机构帮助提供了安全,但这保证了MFCA启动的企业不能冒充一个客户设备和没有验证就进入企业。
客户设备。一个对话框请求用户名和口令以及企业/URL标识符。用户不需要再输入ADID,因为系统已经记住它。客户计算机用正常的方法与VPN网关联系,并验证用户名/口令(通过RADIUS或诸如此类)VPN网关找出客户请求附加的验证以及请求验证它本身。客户开封它的AppContainer(使用Customer AppKey,从Appkey计算以及存储的CustomerSecret),增大Login Counter(128位,不允许为负),再密封它并将它发送给网关,并伴有公开的ADID。一旦VPN具有AppContainer,就将它传递给SAMServer用于验证。客户等待完成。如果网关返回一个错误,则它将用自己的语言提示用户。如果所有的均Ok,则VPN软件开始工作。
Strong Authentication Module(SAM)从VPN Gateway接收用于验证的请求,并伴有客户的ADID和它的AppContainer。它使用ADID作为索引查找Customer AppKey以及所期望的计数值。使用Customer AppKey开封AppContainer。
它校验一个计数及额外的信息。SAM应当允许一个计数范围,如果(Cexpected<=Cactual<Cexpected+10),则验证将为Ok。该目的是涵盖当数据包从客户到服务器丢失时的情况(例如,用户击“重试”按钮许多次)。
如果校验超出范围,则发生错误。它发送一个错误代码及错误参数。如果成功,则它存储新的计数值并发送“Authorization Ok”信息给VPN Gateway。记录错误,并定期地给系统管理人员提交报告。在特定的环境中SAM可警告管理人员,例如如果发生许多次连接失败的尝试,这可能表明有人正试图攻击。
将系统10设计成防卫导致系统和/或系统的保密密钥的破坏和误用的一个不值得信任的软件应用程序的基本威胁模式。在首选实施例中利用SMI和其它相关的硬件装置,扩展威胁模式,系统进一步保护密钥以防运行在“ring zero”、尤其是操作系统本身的部分中不值得信任的程序。
威胁模式,攻击和恢复。下面是许多可识别的威胁、它们的范围以及它们是如何由系统10寻址的讨论。
偷听者窃取AppKey。偷听者可能偷听ARM/SAM通信,并窃取AppKey。然而,他将不能冒充一个客户,因为他也至少需要Customer Secret以及VPNCounter的起始值。
窃取Appkey和Customer Secret。假定一个黑客窃取AppKey及顾客秘密,可能因为他闯入了公司并窃取了ADID数据库中的所有数据。如果检测到偷窃,则可以通过重新注册该计算机以产生一个新的Customer Secret来解决(尽管AppKey不能改变)。如果企业保留AppKey,它可能不需要再重新注册。
威胁延迟。对只有软件的实施例来说,本发明的首选实施例具有基于硬件的安全利益是不可能存在。
本发明的最佳实施例被这样设计,以便基于软件的反向设计工具那个完成它。此外,基于硬件的攻击不能使敌人破坏其它远程计算机。这种保护提供使用CPU的System Management Mode(SMM)来实现。
从SMM中,为窜改而验证软件的下一层(即使用能加密的BIOS的操作系统驱动程序(OSD))。OSD代码被做成明显的篡改一不可能修改它来允许一个没有被SMM代码检测到的无效应用程序使用它。这种验证的操作系统驱动程序轮流校验应用程序没有被修改过。
当用于主密钥的安全存储位置无效时,挫败连接,或者当保密存储装置有效但并不是所有的都收到了一个高级保证时,保密主密钥将被分成存储在多个单元中的共享。同时,使用Shamir的保密共享方案,仅仅要求有限数量的共享取回保密主密钥。
此外,使用基于一个设备附加特性(如驱动程序序列号、图形卡驱动程序版本等)的一个密钥可以加密密钥共享。当设备特性密钥可能很小或可预知时,选择加密从而使使用迭代的加密操作、基于密钥的大小解密要花费大量时间。
每一次要求保密主密钥时要重新连接保密主密钥共享。在每一次连接时,在存储器中用一个指向一个新的存储单元的指针指向连接的保密主密钥。在每一次连接保密主密钥数据块时,进行一个校验以便发现有些数据块是否无效。跟踪设备附加信息的先前值,允许检测一个无效的共享。在无效共享的情况下,保密主密钥被再共享。
SMK/设备附加。本发明的一个只有软件的实施例的请求是当试图做出移动一个主密钥和它的AppContainer到一个新的计算机时,是有能力检测的。为检测这种移动,记录计算机的某些特征。当这几个特征同时改变时,只有软件的系统10检测它并依据它采取行动。
公开有限的主密钥和对话密钥。当使用它们做任何操作时,这种设计限制了保密主密钥和对话密钥的公开。在首选实施例中,所有这样的操作都是使用当在SMM外运行时无效的存储器在SMM中执行。
公开密钥的完整性。在简单的实施例中,公开密钥被包含,并被编译到操作系统驱动程序中。这些可以是在BIOS中包括的相同公开密钥。
VPN客户与TCP/IP堆栈的相互作用如下。客户VPN负责以下的服务VPN客户的配置、对VPN网关的验证、以及将发送至内部企业网的数据包进行加密。一旦登录过程结束,VPN客户的主要工作是检查发送给网络的数据包以便找出它们或者是直接到一个通常的Internet计算机或者到企业网络。
客户检查目的地IP地址。如果数据包是用于在Internet上的一个计算机,则没有修改地发送它。如果数据包是用于VPN网关后面的企业网络,客户加密它并(有时)执行某种地址变换。
客户堆栈是一个分层的结构,如TCP Stack/UDP Stack、NDIS接口(安装程序配置它)、IPSec(通常使用DES和3DES,在某些初始化协商后建立对称)以及NDIS。接收数据包的VPN Gateway将除去加密,然后它们是在网络中是透明的。
在一个使用SPEKE的首选实施例中,客户和网关均生成一个绑定到验证后的用户标识符的新密钥。该密钥可能用于加强将验证作用附加到VPN对话密钥上。
在上面描述的几个位置中,已经描述了可能用在本发明的结构中的几种变体。这些包括(1)将用户赋给设备,使用对于管理人员来说加强的政策来定义用户和设备的有效的特定组合,(2)客户和网关之间、网关和验证服务器之间、以及验证服务器和强大的验证模块之间口令加密,(3)使用一个询问/应答装置而不是使用一个登录计数器,以及(4)将客户安装程序打在一个可从Web站点安装的完整数据包中。
因此,提供用于计算机设备管理机构的系统和方法已经公开了。上面描述的实施例可被理解为仅仅是某些特定实施例的说明,这些特定实施例表示本发明的应用程序的原理。很清楚,许多和其它的方案很容易由本领域的技术人员在不脱离本发明的范畴内做出。
表1AppContainer结构
表2在OSD AppContainer密封过程中的结构改变
表3在SMI AppContainer密封过程中的结构改变
表4最终的密封结果
表5MK Container结构
表6在OSD MK Container密封过程中结构改变
表7最终的密封结果
表8SignedContainer结构
表9最终的密封结构
表1
从表1所示的测定结果可知,如果平行线透射率为最大的情况下的极角θ1在-40°≤θ1≤0°的范围、0°≤θ2≤40°的范围内,那么可以确保与现有品相同程度的亮度,而如果在-30°≤θ1≤-10°的范围、10°≤θ2≤30°的范围内,那么可获得亮度比现有品良好的液晶显示装置。
(试验例3)准备将指向性前方散射膜的法线方向的平行线透射率T(0,0)改变为各种值所得的指向性前方散射膜,在荧光灯点亮下的办公室中比较配有该指向性前方散射膜的液晶显示装置的亮度。比较的现有品与前面试验例中使用的制品相同。将认为比现有品的反射型彩色液晶显示装置明显亮的制品记为○、将同等亮度的制品记为△,而将亮度暗的制品记为×,并示于以下的表2中。
表2
表11最后的密封PubkContainer结构
表12最后的密封的PubkContainer结构
表13最后的密封结构
表1412.5.2授权缓冲器32位 32位 160位 64bits 8bits
表15注册的应用程序表32位 32位 160位 64bits
权利要求
1.一种用于使用和保护对主加密密钥的访问的系统,包括非易失性存储器;一个系统初始化过程,其中在系统初始化过程中从该非易失性存储器读取该主密钥;将从该主密钥导出的一个敏感数据写入到一个隐蔽的存储单元;以及禁止由运行在该系统上的任何程序访问该非易失性存储器直到下一次系统初始化过程开始为止;用于防止由运行在系统的正常操作模式中的程序访问该隐蔽的存储单元的装置;以及用于允许由运行在系统的一个受限操作模式中的程序访问该隐蔽的存储单元的装置。
2.如权利要求1所述的系统,其特征在于所述的敏感数据是该主密钥。
3.如权利要求1所述的系统,其特征在于所述的敏感数据是由该主密钥推导而来的。
4.如权利要求3所述的系统,其特征在于所述的敏感数据是一个从存储在磁盘上的加密数据检索而来的第二密钥,该存储数据用该主密钥进行加密。
5.如权利要求1所述的系统,其特征在于在响应于一个通电或复位信号开始的该系统初始化过程中,在BIOS ROM中的软件控制该系统。
6.如权利要求1所述的系统,其特征在于该非易失性存储器是一个由锁存器控制的具有读和写访问的非易失性随机存取存储器;由于响应一个通电或复位事件的硬件功能,该锁存器在系统初始化过程开始时被打开,因此允许系统访问该非易失性随机存取存储器;以及在系统初始化过程中关闭该锁存器,因此不允许系统访问该非易失性随机存取存储器直到下一次系统初始化开始为止。
7.如权利要求1所述的系统,其特征在于所述的隐蔽存储器是不能由运行在系统的正常操作模式中的任何程序访问的系统管理随机存取存储器;以及所述的受限的操作模式是系统管理模式,在系统管理模式中允许访问系统管理随机存取存储器。
8.如权利要求1所述的系统,其特征在于所述的隐蔽存储器仅对由操作系统访问是有限制的,而且不能由运行在系统的正常操作模式中的任何程序访问;以及所述的受限的操作模式是由保留由操作系统软件使用的CPU保护环控制的。
9.一种用于在存储器隐蔽一个主加密密钥的系统,包括通电软件,其中从非易失性存储器读取一个主密钥;停止对非易失性存储器的访问,以便直到下一次系统复位时访问才能变得再有效;将从该主密钥导出的敏感数据写入一个隐蔽的地址空间;以及只有运行在系统的一个受限操作模式中的程序才能访问该隐蔽的地址空间中的敏感数据。
10.一种用于通过限制加密密钥对于一个应用程序的可用性,控制对应用程序的数据的读和写访问的方法,该方法包括一个主密钥;一个应用程序容器,保存该应用程序想访问的数据的密封或开封格式;一个加密看守模块,执行组成调用应用程序的部分字节的加密摘要以便计算一个加密变换;以及一个加密处理模块,包括用于检查该应用程序容器和加密变换的完整性校验、以及主密钥,以确定是否允许该应用程序开封在给定的应用程序容器中的该数据,或当密封数据时,改变它以增加完整性校验信息。
11.如权利要求10所述的方法,其特征在于由加密处理模块执行的保密方法,通过使用从至少该主密钥和密码变换中导出的一个密钥来解密在应用程序容器中的数据。
12.如权利要求10所述的方法,进一步包括由加密处理模块执行的保密方法,使用从至少该主密钥和密码变换中导出的一个密钥加密在应用程序容器中的数据。
13.如权利要求12所述的方法,其特征在于在执行加密前,该保密方法将密码变换增加到应用程序容器中。
14.一种用于通过限制一个加密密钥对于在特定设备上的应用程序的可用性,来控制对应用程序的数据的访问的方法,包括加密处理模块已知的一个密钥;一个应用程序容器数据结构,包含该应用程序想要访问的数据的加密密封格式;一个加密看守功能,其中截取应用程序级程序和加密处理模块之间的所有访问;包括一个装置,用于检查正试图访问加密服务器或数据的程序在存储器内可执行的图象的部分字节;计算该调用程序的存储器内图象的部分字节的加密摘要,以计算应用程序的加密变换;以及由加密处理模块执行的完整性校验方法,检查该应用程序容器数据结构和加密变换,以及该主密钥,用于确定是否允许该应用程序开封在指定的应用程序容器数据结构中的数据,或者当开封该数据时,改变它以增加完整性校验信息。
15.如权利要求14所述的方法,进一步包括由加密处理模块执行的保密方法,使用从至少该主密钥和加密变换中导出的一个密钥加密或解密在应用程序容器中的数据,以及当加密数据时,在执行加密前,它可选地将加密变换增加给应用程序容器数据结构。
16.如权利要求14所述的方法,其特征在于加密看守功能是同时或先于给定一个授权缓冲器,该缓冲器指定用于应用程序的允许的操作,且加密看守功能确认请求操作是允许的。
17.如权利要求14所述的方法,其特征在于完整性校验方法包括以下步骤从加密变换和主密钥中导出一个加密变量,或从加密变换、主密钥和由应用程序的一个组件选择的一个加密变量中导出第二个加密变量,这个导出的密钥被用来校验存储在应用程序容器数据结构中的信息验证代码。
18.如权利要求14所述的方法,其特征在于完整性校验方法包括步骤使用由主密钥导出的一个密钥解密该应用程序容器数据结构的一部分,并将部分结果值与部分加密变换进行比较,如果两部分相同的话,则允许访问。
19.如权利要求14所述的方法,其特征在于该保密步骤包括步骤从加密变换和主密钥以及可选的其他信息中导出一个加密变量骤,或从加密变换、主密钥和由应用程序的一个组件选择的一个加密变量、及可选的其它信息中导出第二个加密变量,且该导出的密钥被用来解密或加密部分应用程序容器数据结构。
20.如权利要求19所述的方法,其特征在于通过以某个次序连接这些依赖值,用一个或多个MD5、SHA1或SHA-256散列函数的应用程序执行该密钥导出。
21.如权利要求14所述的方法,其特征在于部分加密处理模块在系统管理过程中执行中断。
22.一种用于在另一个包含具有一个设备管理机构的计算机的帮助下,在一个已识别的设备上验证一个已识别的应用程序到另一个含有验证服务器的计算机的方法,该方法包括一个登记过程,包括步骤a)在系统管理中断(SMI)过程中在设备上执行第一加密操作,以产生一个发送给所述设备管理机构的结果,以及b)在系统管理中断(SMI)过程中在设备上执行第二加密操作以处理由该设备管理机构产生且由设备接收的一个值;一个注册过程,包括步骤a)在系统管理中断(SMI)过程中在设备上执行第一加密操作以产生一个发送给所述验证服务器的结果,以及b)由验证服务器执行第二加密操作以产生一个存储用于在验证方法中使用的加密变量,以及c)在SMI中断过程中在该设备上执行可选的第三加密操作以处理一个由验证服务器产生且由该设备接收的值;一个验证过程,包括步骤a)在系统管理中断(SMI)过程中在该设备上执行第一加密操作以产生被一个发送给验证服务器的验证数据,以及b)由验证服务器在从设备接收的验证数据上执行第二加密操作,使用在登记方法中存储的至少该加密变量来确定验证的结果。
23.一种用于在一个已识别的设备上验证一个已识别的应用程序、或者提供一个用于识别已识别设备的用户的第二因子给另一个含有PASS服务器的计算机的方法,该方法包括一个应用程序,其中a)执行一个包含与设备管理机构和验证服务器通信的登记方法,以在设备上创建一个应用程序容器数据结构,其中应用程序容器结构是与应用程序加密相关的;以及b)存储凭证信息,以及其中,验证服务器,用于存储一个应用程序容器数据结构的加密变量;在已识别的设备上运行应用程序,执行一个包括以下步骤的验证方法a)开封存储了凭证的应用程序数据结构;b)修改该凭证;c)重新密封应用程序容器数据结构;d)将识别信息和至少部分重新封密的AppContainer发送给验证服务器;其中,在执行应用程序代码的同一CPU上的SMI过程中,至少发生部分的重密封操作;以及其中验证服务器a)接收辩识信息和至少部分的应用程序容器数据结构,b)使用辩识信息查找或计算一个加密变量来开封应用程序容器数据结构,c)如果开封的应用程序容器具有可接受的值,则在特定设备上的特定应用程序被认为是已验证的;以及d)存储与应用程序容器数据结构有关的一个密钥。
24.一种为验证、保密性、完整性、授权、检查或数字权利管理的目的,用于创建和利用一个或多个在设备上的虚拟标记的方法,该方法包含一个用于每一种虚拟标记的应用程序;一个用于每一个特定种类的虚拟标记的应用程序容器;加密看守组件,计算一个调用应用程序的加密变换,其中该调用应用程序正请求一个加密处理组件的加密服务;其中加密看守组件已知一个或多个使用期长的对称密钥;其中通过CryptoGate组件访问加密处理组件;其中加密处理组件已知一个或多个使用期长的对称密钥和一个或多个使用期长的公开密钥;以及其中加密处理组件执行应用程序容器数据结构的加密密封和开封,在系统管理中断(SMI)的过程中执行部分的加密操作;其中加密处理组件通过校验部分应用程序的代码或静态数据的数字签名、使用已经被载入到CryptoEngine中的一个公开密钥和加密变换,来校验调用应用程序的完整性;其中加密变换值包括部分调用程序在存储器内的图像的一个最近计算的加密散列;其中加密看守和加密处理组件a)从主密钥和加密变换中导出一个用于为开封应用程序容器数据结构的密钥,b)使用导出的密钥来校验在应用程序容器数据结构上的信息验证代码,以及如果信息验证代码是正确的,则返回一个错误,以及c)使用导出的密钥来解密在应用程序容器数据结构中的数据并将它返回给应用程序。
25.一种安全地将私有密钥和与设备有关的应用程序相关联的方法,包括创建一个应用程序容器,其含有由与设备有关的一个对称密钥保护的私有密钥。
全文摘要
用于使用一个存储在受保护的非易失性存储器的主密钥,进行设备验证的系统和方法。该主密钥被用来导出被传递到只能在计算机系统的特许操作模式下访问的存储器中的敏感数据。该敏感数据和主密钥不能直接由没有运行在特许操作模式中的程序访问。主密钥被用来导出一个或多个用来保密一个给应用程序/设备对的专用数据的应用程序密钥。非特许的程序能请求运行在特许模式中的函数以使用这些应用程序密钥。该特许的模式程序校验非特许调用应用程序的完整性以确保它具有管理机构和/或完整性以执行每一个请求的操作。一个或多个设备管理机构服务器用来公布和管理主密钥和应用程序密钥。
文档编号G06F21/24GK1380610SQ0114546
公开日2002年11月20日 申请日期2001年11月23日 优先权日2001年4月9日
发明者J·-P·阿布格拉尔, R·W·巴尔德温, J·D·巴尔, J·A·卡斯拉斯, D·P·亚布伦, T·J·马基, P·科特拉, K·王, S·D·威廉斯 申请人:凤凰技术有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1