TPM分析笔记(十一)TPM 密钥组织架构(TPM Key Hierarchy)

接上文TPM分析笔记(十)TPM 组织架构(TPM hierarchy)

一、Key hierarchies

TPM的主要功能之一是生成密钥并使用这些密钥来证明有关TPM的事实。
TPM没有直接存储密钥,而是具有称为“种子”的秘密值,这些值永远不会离开TPM并在重新启动时保持不变。种子用于确定性地生成密钥,从而可以识别TPM,即使外部存储被擦除(例如,在操作系统安装期间)。

有三个种子和相关层次结构:

  • 背书:用于识别TPM的密钥。
  • 存储:本地应用程序使用的密钥。
  • 平台:(我们将忽略这一个)TPM用于其自身操作的键。

虽然可以创建任何hierarchy,但有足够多的不透明限制,标准配置是唯一常见的配置。为了进行配置,我们将生成三个众所周知的密钥(EK Key、SRK和AIK Key),并使用它们来认证应用程序使用的密钥。

在这里插入图片描述

There are two main classifications of keys: restricted and non-restricted.
Restricted keys are used to sign or decrypt TPM state or challenges: asserting boot measurements, or proving that a key is resident on the same TPM. In our hierarchy the EK, SRK, and AIK are all restricted keys.
Non-restricted keys are intended for general use. These can be used as TLS client keys, to sign documents, etc. The application keys will be non-restricted.

1.1 EK密钥

EK密钥是特殊的,因为密钥生成使用众所周知的模板。这意味着 TPM 制造商、设备制造商和最终用户将始终使用相同的种子密钥。

在某些情况下,TPM 制造商会为 EK 签署证书并将其存储在 NVRAM 中。在极少数情况下,设备制造商还将颁发平台证书,该证书引用 EK 证书并保存设备序列号等信息。这些证书可以与 EK 结合使用以引导信任。

在 GCP 上,getShieldedInstanceIdentity API 可用于获取 EK 证书(我们将保留该证书以供下次使用)。

让我们生成一个EK密钥并存储其上下文以供以后使用:

RSA密钥模板如下:
在这里插入图片描述

f, err := os.OpenFile("/dev/tpmrm0", os.O_RDWR, 0)
if err != nil {
        log.Fatalf("opening tpm: %v", err)
}
defer f.Close()

tmpl := tpm2.Public{
        Type:    tpm2.AlgRSA,
        NameAlg: tpm2.AlgSHA256,
        Attributes: tpm2.FlagFixedTPM | // Key can't leave the TPM.
                tpm2.FlagFixedParent | // Key can't change parent.
                tpm2.FlagSensitiveDataOrigin | // Key created by the TPM (not imported).
                tpm2.FlagAdminWithPolicy | // Key has an authPolicy.
                tpm2.FlagRestricted | // Key used for TPM challenges, not general decryption.
                tpm2.FlagDecrypt, // Key can be used to decrypt data.
        AuthPolicy: []byte{
                // TPM2_PolicySecret(TPM_RH_ENDORSEMENT)
                // Endorsement hierarchy must be unlocked to use this key.
                0x83, 0x71, 0x97, 0x67, 0x44, 0x84,
                0xB3, 0xF8, 0x1A, 0x90, 0xCC, 0x8D,
                0x46, 0xA5, 0xD7, 0x24, 0xFD, 0x52,
                0xD7, 0x6E, 0x06, 0x52, 0x0B, 0x64,
                0xF2, 0xA1, 0xDA, 0x1B, 0x33, 0x14,
                0x69, 0xAA,
        },
        RSAParameters: &tpm2.RSAParams{
                Symmetric:  &tpm2.SymScheme{Alg: tpm2.AlgAES, KeyBits: 128, Mode: tpm2.AlgCFB},
                KeyBits:    2048,
                ModulusRaw: make([]byte, 256),
        },
}

ek, pub, err := tpm2.CreatePrimary(f, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", tmpl)
if err != nil {
        log.Fatalf("creating ek: %v", err)
}
out, err := tpm2.ContextSave(f, ek)
if err != nil {
        log.Fatalf("saving context: %v", err)
}
if err := ioutil.WriteFile("ek.ctx", out, 0644); err != nil {
        log.Fatalf("writing context: %v", err)
}

pubDER, err := x509.MarshalPKIXPublicKey(pub)
if err != nil {
        log.Fatalf("encoding public key: %v", err)
}
b := &pem.Block{Type: "PUBLIC KEY", Bytes: pubDER}
pem.Encode(os.Stdout, b)

有一些合理的模板字段,然后有authPolicyauthPolicy 是一个表示一系列授权的哈希值。要使用策略访问密钥,会话会重复授权序列,从而使会话哈希与 authPolicy 匹配并授予对密钥的访问权限。我们将在很大程度上忽略会话和策略(并坚持使用空密码!),但稍后将有一个设置会话以访问EK的示例。

由于密钥生成是确定性的,因此此程序将始终在同一设备上打印相同的结果:

$ go build -o bin/ek ek.go
$ sudo ./bin/ek
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+N1FqzITQPBH4v/cLQdd
rlfKYEtgTvDcLVAxfckosZWa9PuqRdrxOcif1dFYsSeL7gbwmzVswMNA1cYdiBNV
cpkU3DkQGvSTFJXc46lUFNtsH3X69ONB3i+eiH3SDEj3xfZ8BoTVvzwly7idwfpL
QAfj4531ehrO0yt7AhF7bfjdlTrTHt5IiRIJ9oV5IWfs18TwrUhVAdPYjzUU3gG4
F5TLB9asBlyMCq9pbvXf1aC/eGSQ1uD06Qn5o5j2Sc2Ut9eHrfONIpUEb4Awz3LO
TJdtUGmQVJPTGWIw/WJ53dtXsE+FpVuYVqXXLMYiASzq8x4MiEgw884j3NRXByOt
gQIDAQAB
-----END PUBLIC KEY-----
$ sudo ./bin/ek
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+N1FqzITQPBH4v/cLQdd
rlfKYEtgTvDcLVAxfckosZWa9PuqRdrxOcif1dFYsSeL7gbwmzVswMNA1cYdiBNV
cpkU3DkQGvSTFJXc46lUFNtsH3X69ONB3i+eiH3SDEj3xfZ8BoTVvzwly7idwfpL
QAfj4531ehrO0yt7AhF7bfjdlTrTHt5IiRIJ9oV5IWfs18TwrUhVAdPYjzUU3gG4
F5TLB9asBlyMCq9pbvXf1aC/eGSQ1uD06Qn5o5j2Sc2Ut9eHrfONIpUEb4Awz3LO
TJdtUGmQVJPTGWIw/WJ53dtXsE+FpVuYVqXXLMYiASzq8x4MiEgw884j3NRXByOt
gQIDAQAB
-----END PUBLIC KEY-----

1.2 SRK

出于某种原因,在背书hierarchy下创建密钥可能很烦躁,因此设置倾向于在存储hierarchy下创建密钥。EK密钥仍然可以在其他hierarchy下证明密钥,因此,当我们生成存储根密钥时,我们实际上不会将其用于证明。SRK 仅充当其他键的父级。

这对于EK看起来很熟悉,并且具有定义模板的类似规范。但是,不是在“HandleEndorsement”下创建密钥,而是在“HandleOwner”下创建它,表示存储hierarchy。

f, err := os.OpenFile("/dev/tpmrm0", os.O_RDWR, 0)
if err != nil {
        log.Fatalf("opening tpm: %v", err)
}
defer f.Close()

tmpl := tpm2.Public{
        Type:    tpm2.AlgRSA,
        NameAlg: tpm2.AlgSHA256,
        Attributes: tpm2.FlagFixedTPM | // Key can't leave the TPM.
                tpm2.FlagFixedParent | // Key can't change parent.
                tpm2.FlagSensitiveDataOrigin | // Key created by the TPM (not imported).
                tpm2.FlagUserWithAuth | // Uses (empty) password.
                tpm2.FlagNoDA | // This flag doesn't do anything, but it's in the spec.
                tpm2.FlagRestricted | // Key used for TPM challenges, not general decryption.
                tpm2.FlagDecrypt, // Key can be used to decrypt data.
        RSAParameters: &tpm2.RSAParams{
                Symmetric:  &tpm2.SymScheme{Alg: tpm2.AlgAES, KeyBits: 128, Mode: tpm2.AlgCFB},
                KeyBits:    2048,
                ModulusRaw: make([]byte, 256),
        },
}

srk, _, err := tpm2.CreatePrimary(f, tpm2.HandleOwner, tpm2.PCRSelection{}, "", "", tmpl)
if err != nil {
        log.Fatalf("creating srk: %v", err)
}
out, err := tpm2.ContextSave(f, srk)
if err != nil {
        log.Fatalf("saving context: %v", err)
}
if err := ioutil.WriteFile("srk.ctx", out, 0644); err != nil {
        log.Fatalf("writing context: %v", err)
}

1.3 Attesting keys

虽然在本地生成密钥是可以的,但如果你能证明它们存储在硬件中,硬件密钥会更有趣。

TPM 提供了证明两个密钥驻留在同一 TPM 中的功能。虽然这对信任层次结构中的第一个密钥没有帮助,但每个后续密钥都可以由较早的密钥来证明。这允许我们将密钥集链接回认可密钥,如果我们相信 EK 存储在 TPM 中,则我们以传递方式信任所有其他密钥也存储在 TPM 中。

二、密钥作用介绍

在这里插入图片描述
在这里插入图片描述

  • Storage Keys:存储密钥,用来加密数据和其它密钥的通用非对称密钥,这里的其它密钥可以是另外一个存储密钥,也可以是绑定密钥或签名密钥。它本身是长度2048bitRSA私钥,它既可以是可迁移密钥,也可以是不可迁移密钥。

  • SRK:Storage Root Key,存储根密钥,是整个系统拥有一个最高权限的存储密钥,这个最高级密钥也就是存储根密钥。它很特殊,在每个用户创建的时候生成,管理这个用户的所有数据,也就是存储可信根(Root of Trust for Storage, RTS)和签署密钥(Endorsement Key,EK)一样,一个TPM仅存在唯一一个。所有其它的密钥都在存储根密钥的保护之下

  • 签名密钥(Signing Key):是非对称密钥,用于对应用数据和信息签名。签名密钥可以是可迁移或不可迁移的。可迁移密钥能够在TPM之间传递,通过迁移密钥传递保密数据。TPM中的签名密钥都遵循RSA签名密钥的标准,它们有若干种不同长度。TPM能够正确地进行处理的最大密钥长度是2048bit。

  • 签署密钥,或背书密钥(Endorsement Key,EK)是一个TPM平台的不可迁移的解密密钥,它是一个2048bitRSA密钥对。它生成于平台的生产过程中,代表着每个平台的真实身份,每个平台都拥有唯一的一个。在确定平台所有者时,用于解密所有者的授权数据,还有解密与生成AIK相关的数据。签署密钥从不用作数据加密和签名。签署密钥的主要功能是生成身份证明密钥(AIK)和建立TPM平台的所有者,由TPM的所有者来生成存储根密钥SRK,使用SRK来加密、存储其他的密钥。
    EK可以通过密钥生成服务器,采用两种方法来产生:一种使用TPM命令,TCG规范定义了一组背书密钥操作命令,其中创建背书密钥对的命令为TPM_CreateEndorsementKeyPair,产生密钥长度要求至少2048位。另外一种方法是密钥注入技术,在信任制造商的前提下,由TPM制造商产生背书密钥对,然后采用人工方式注入,注入方法有:键盘输入、软盘输入、专用密钥抢输入等。
    对比这两种方法,前者必须依赖硬件中提供受保护的功能和被隔离的位置,从而保证在设备内部产生密钥对,而且密钥对是在篡改保护的环境下产生,能够很好地减少密钥对泄露的风险。

  • AIK:认证身份密钥,或平台身份认证密钥(Attestation Identity Key)是不可迁移密钥。专用于对TPM产生的数据(如TPM功能、PCR寄存器的值等)进行签名,用来证明平台的身份和平台的环境配置,凡是经过AIK签名的实体,都表明已经经过TPM的处理。每个用户可以拥有多个AIK,每个AIK的生成都需要可信第三方的支持。

  • 绑定密钥(Binding Keys): 用于在一个平台中加密小规模数据(如对称密钥),然后在另一个TPM平台上进行解密。由于使用平台所特有的密钥加密,所以与该平台绑定。这个密钥的用法同传统非对称密钥加密相同。

  • 密封密钥(Sealing Keys):内置TPM的计算机可以创建一个密钥,该密钥不仅被绑定,而且还被连接到特定硬件或软件条件,这就是密封密钥。首次创建密封密钥时TPM将记录配置值和文件哈希的快照。仅在这些当前系统值与快照中的值想匹配时才能解封或释放密封密钥。

  • 遗留密钥(legacy Keys):在TPM之外生成,它们被定义为可迁移的,在被用来签名或加密之后才能载入TPM。这些密钥用在一些需要在平台之间传递数据的场合。

  • 鉴别密钥(Authentication Keys):用来保护涉及TPM传输会话的对称密钥。

  • Key Management:为了更有效地管理存储在TPM外边的密钥,引进一种密钥缓冲管理机制(Key Cache Manager),它主要管理TPM中受限制的资源,并且对应用程序调用隐藏这些限制。应用程序可以通过利用KCM来载入密钥到TPM中,并假定此密钥可以进一步利用。KCM负责保证当应用程序某个命令需要密钥时,这个已经被应用程序载入的密钥存在于TPM中。如果所有TPM资源被占用,KCM需要释放资源将不经常使用的密钥从TPM取出来,以便为那些经常进出TPM的密钥腾出空间,将需要的密钥放入TPM。应用程序需要利用KCM来将密钥载入TPM中。

  • 可迁移密钥和不可迁移密钥:在整个TPM/TCM的密钥体系中,每个密钥在开始创建的时候都需要指定密钥属性。密钥按照属性不同分为:可迁移密钥(Migratable Key)和不可迁移密钥(Non-Migratable Key)。可迁移密钥并不局限于某个特定平台,可以由平台用户的控制在平台之间迁移。不可迁移密钥则永久地与某个指定平台关联。不可迁移密钥能够用来加密保护可迁移密钥,反之则不可。
    不可迁移密钥由TPM内部产生,在TPM产生之后就被打上了TPM的标记。不可迁移密钥本身的安全性要比可迁移密钥高,因为不可迁移密钥全部由TPM内部产生并且从产生到销毁整个周期私钥部分都不会离开TPM(除非不可迁移密钥转化为可迁移密钥,这个时候安全级别降低,注意的是由于可迁移密钥安全级别低所以无法转化为不可迁移密钥)。同时不可迁移密钥可以被TPM签名,从而可以向挑战者或者用户证明其不可迁移的属性,从而证明其安全性。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔的乌龟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值