将 TPM public 密钥序列化为 DER 或 PEM

Serialize TPM public key to DER or PEM

我正在使用 TPM 即时生成密钥对,最终我想格式化并将一对密钥对的 public 部分输出到一个文件中,以便于使用由第三方。

为了解决 TPM,我使用 TSS.MSR C++ API

使用以下模板成功创建 RSA2048 主键后:

TPMT_PUBLIC keyDescription(TPM_ALG_ID::SHA256,
                           TPMA_OBJECT::sign | TPMA_OBJECT::fixedParent | TPMA_OBJECT::fixedTPM |
                             TPMA_OBJECT::sensitiveDataOrigin | TPMA_OBJECT::userWithAuth,
                           nullVector,
                           TPMS_RSA_PARMS(TPMT_SYM_DEF_OBJECT(TPM_ALG_ID::_NULL, 0, TPM_ALG_ID::_NULL),
                                          TPMS_SCHEME_RSASSA(TPM_ALG_ID::SHA256), 2048, 65537),
                           TPM2B_PUBLIC_KEY_RSA(nullVector));

tpm.ReadPublic(primaryKey) 的输出内容如下:

class ReadPublicResponse                                                                                                                                                                                                                      
{                                                                                                                                                                                                                                             
    UINT16 outPublicSize = 0xffff (65535)                                                                                                                                                                                                     
    TPMT_PUBLIC outPublic = class TPMT_PUBLIC                                                                                                                                                                                                 
    {                                                                                                                                                                                                                                         
        TPM_ALG_ID type = RSA (0x1)                                                                                                                                                                                                           
        TPM_ALG_ID nameAlg = SHA256 (0xb)                                                                                                                                                                                                     
        TPMA_OBJECT objectAttributes = fixedTPM |                                                                                                                                                                                             
                                        fixedParent |                                                                                                                                                                                         
                                        sensitiveDataOrigin |                                                                                                                                                                                 
                                        userWithAuth |                                                                                                                                                                                        
                                        encrypt                                                                                                                                                                                               
                                        (0x40072)                                                                                                                                                                                             
        UINT16 authPolicySize = 0x00 (0)                                                                                                                                                                                                      
        BYTE[] authPolicy = []                                                                                                                                                                                                                
        TPMU_PUBLIC_PARMS parameters = class TPMS_RSA_PARMS                                                                                                                                                                                   
        {                                                                                                                                                                                                                                     
            TPMT_SYM_DEF_OBJECT symmetric = class TPMT_SYM_DEF_OBJECT                                                                                                                                                                         
            {                                                                                                                                                                                                                                 
                TPM_ALG_ID algorithm = _NULL (0x10)                                                                                                                                                                                           
                UINT16 keyBits = 0xcdcd (52685)                                                                                                                                                                                               
                TPM_ALG_ID mode = ? (0xcdcd)                                                                                                                                                                                                  
            }                                                                                                                                                                                                                                 
            TPM_ALG_ID schemeScheme = RSASSA (0x14)                                                                                                                                                                                           
            TPMU_ASYM_SCHEME scheme = class TPMS_SIG_SCHEME_RSASSA                                                                                                                                                                            
            {                                                                                                                                                                                                                                 
                TPM_ALG_ID hashAlg = SHA256 (0xb)                                                                                                                                                                                             
            }                                                                                                                                                                                                                                 
            UINT16 keyBits = 0x800 (2048)                                                                                                                                                                                                     
            UINT32 exponent = 0x10001 (65537)                                                                                                                                                                                                 
        }                                                                                                                                                                                                                                     
        TPMU_PUBLIC_ID unique = class TPM2B_PUBLIC_KEY_RSA                                                                                                                                                                                    
        {                                                                                                                                                                                                                                     
            UINT16 size = 0x100 (256)                                                                                                                                                                                                         
            BYTE[] buffer = [a1f2152a f32f05ba fb8bd712 dde41bbc 1ec60134 dfba6dc3 88d18215 9affe8b0 5ca27d55 488d65df 8ac87496 4afe003c 701a82b0 5422797e 82347463 81a89a68 08066973 27ed9454 6efe12c8 ed454a3d 7ef3991f 04639a10 dafb6261 56
3fabb1 2f81feb0 0e2bd6f7 bb0ea93c ec735371 53578dce 939486a2 a77c740b 69cef375 b34b3b5e 6a7224f9 3444873a 2c5de6b5 a1e954ec 2e8db8ad 16876137 f3101c84 fcf0009c e338d83c a94f6dca a25098d0 0a120c03 bc165a51 adf09476 4ec22a0d 0c8ab5c1 34e819
40 3255404e 884817a8 9eb1c705 e2f3f36b 772d71e5 3ea42bef 310eb972 91734553 276b7cbf 00d2a471 a698478b 0d7daa3b 3abd1c39 6f877c5f]                                                                                                             
        }                                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                                         
    UINT16 nameSize = 0x22 (34)                                                                                                                                                                                                               
    BYTE[] name = [000b04d3 b7e1a981 edcb0ab7 0b3a613c aece385b 1137807b c5ecdf35 4999f70f 4abd]                                                                                                                                              
    UINT16 qualifiedNameSize = 0x22 (34)                                                                                                                                                                                                      
    BYTE[] qualifiedName = [000b9017 ad0262c1 ebf46346 edf8046a 0784ce4b c7a3c446 5d6b087c 5e55133d 9fa0]                                                                                                                                     
}                                                                                                                                                                                                                                             

将关键数据序列化为第三方可以理解的内容(pem、der、...)的最简单方法是什么 - 我有我需要的一切吗?

这可以通过 Botan 或 OpenSSL 等库来实现。与 Botan 的关系非常简单:

auto rsaPublicKey = Botan::RSA_PublicKey(Botan::BigInt(modulus), exponent);
std::cout << Botan::X509::PEM_encode(rsaPublicKey);

输出:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjpnwa0nQEcizailiN487
K5xazxax7vqNuxdgJnVb8sOG0jLCpLuLpsit5MD7V8q9ks7GLRrSSc1cam0H1C0a
v9NHZTlAP+KGI1h68xDS8kr08Af3GHN7pnbR4nh5kez/3nNMx7mEmenUZ4+YmouF
xBotH2ZhwOhs/Mw1IGw29c3lI6hvGwcHfGPHPTRKQoN6QG4IFQLNI+eF9W5YJXhA
rDFNn1IodQ6OsIYg3te2HeyqVS7B5UQSOJr4UG8+/I08FRiQ2D4Jeb6Fz6jQsznc
ng6zqNfgBGkSQWuLisd0QRjI3ekdubIAENPKahRHbmQdzjnhhpCimy7XcuA55aZN
5wIDAQAB
-----END PUBLIC KEY-----

此外,使用 openSSL 验证密钥的格式是否正确:
$ openssl rsa -pubin -in pubkey.pem -text --noout

使用 Botan 库,详细代码可能如下所示:


TPM_HANDLE persistentHandle = ....;
....

auto mod = persistentPub.outPublic.unique->toBytes();
auto rsaPublicKey = Botan::RSA_PublicKey(Botan::BigInt(mod.data(), mod.size()), 65537);
std::cout << Botan::X509::PEM_encode(rsaPublicKey);