Ověření identity modulu Trusted Platform Module
Zařízení s čipem TPM (Trusted Platform Module) se můžou spoléhat na ověření identity, aby dokázala, že není ohrožena integrita spouštění, a také pomocí procesu měřeného spouštění k detekci stavů funkcí spouštění v rané fázi.
Rostoucí počet typů zařízení, zavaděčů a útoků na spouštěcí zásobník vyžaduje, aby se odpovídajícím způsobem vyvíjelo řešení ověření identity. Otestovaný stav zařízení se řídí zásadami ověření identity, které se používají k ověření obsahu důkazů platformy.
Tento článek obsahuje přehled ověření identity pomocí čipu TPM a možností podporovaných Azure Attestation.
Přehled
Ověření identity TPM začíná ověřováním samotného čipu TPM až do bodu, kdy předávající strana může ověřit tok spouštění.
Obecně platí, že ověření identity pomocí čipu TPM vychází z následujících pilířů.
Ověření pravosti čipu TPM
Ověření pravosti čipu TPM ověřením čipu TPM:
- Každý čip TPM se dodává s jedinečným asymetrickým klíčem označovaným jako ověřovací klíč (EK). Tento klíč je vypálen výrobcem. Veřejná část tohoto klíče se označuje jako EKPub. Přidružený privátní klíč se označuje jako EKPriv. Některé čipy TPM mají také certifikát EK vydaný výrobcem pro EKPub. Tento certifikát se označuje jako EKCert.
- Certifikační autorita (CA) naváže vztah důvěryhodnosti k čipu TPM prostřednictvím EKPub nebo EKCert.
- Zařízení certifikační autoritě prokáže, že klíč, pro který se certifikát požaduje, je kryptograficky vázán na EKPub a že čip TPM vlastní EKPriv.
- Certifikační autorita vydá certifikát se speciálními zásadami vystavování, které označují, že klíč je teď otestovaný jako chráněný čipem TPM.
Ověření měření provedených během spouštění
Pomocí Azure Attestation ověřte měření provedená během spouštění:
- V rámci důvěryhodného a měřeného spuštění se každý krok ověří a změří do čipu TPM. Různé události se měří pro různé platformy. Další informace o procesu měřeného spouštění ve Windows najdete v tématu Zabezpečení procesu spouštění systému Windows.
- Při spuštění se vygeneruje klíč identity ověření identity. Používá se k poskytování kryptografického důkazu službě ověření identity, že používaný čip TPM byl po ověření EK vystavený certifikát.
- Předávající strany mohou provést ověření proti Azure Attestation, které lze použít k ověření měření provedených během procesu spouštění.
- Předávající strana se pak může spoléhat na příkaz ověření identity, který bude chránit přístup k prostředkům nebo jiným akcím.
Koncepčně je možné vizualizovat ověření identity pomocí čipu TPM, jak je znázorněno v předchozím diagramu. Předávající strana použije Azure Attestation k ověření integrity platformy a jakéhokoli porušení slibů. Proces ověření vám dává jistotu, že budete spouštět úlohy nebo poskytovat přístup k prostředkům.
Ochrana před škodlivými spouštěcími útoky
Techniky útoku pro dospělé mají za cíl infikovat bootovací řetězec. Spouštěcí útok může útočníkovi poskytnout přístup k systémovým prostředkům a umožnit útočníkovi skrýt se před antimalwarovým softwarem. Důvěryhodné spouštění funguje jako první pořadí obrany. Použití důvěryhodného spouštění a ověření identity rozšiřuje možnosti na předávající strany. Většina útočníků se v procesu spouštění pokouší obejít zabezpečené spuštění nebo načíst nežádoucí binární soubor.
Vzdálené ověření identity umožňuje předávajícím stranám ověřit, jestli není porušení slibů v celém spouštěcím řetězci. Například vyhodnocení zabezpečeného spuštění službou ověření identity ověřuje hodnoty zabezpečených proměnných měřených rozhraním UEFI.
Instrumentace měřeného spouštění zajišťuje, že kryptograficky svázaná měření se po jejich provedení nedají změnit a že měření může provádět pouze důvěryhodná komponenta. Z tohoto důvodu k zajištění povolení stačí ověření zabezpečených proměnných.
Azure Attestation zprávu podepíše, aby byla zachována integrita ověření identity, aby byla chráněna před útoky man-in-the-middle.
Můžete použít jednoduchou zásadu:
version=1.0;
authorizationrules {
=> permit();
};
issuancerules
{
[type=="aikValidated", value==true] &&
[type=="secureBootEnabled", value==true] => issue(type="PlatformAttested", value=true);
};
Někdy nestačí ověřit při spouštění jenom jednu komponentu. Ověřování doplňkových funkcí, jako je integrita kódu nebo integrita kódu chráněného hypervisorem (HVCI) a Ochrana System Guard Secure Launch přidává do profilu ochrany zařízení. Potřebujete také možnost nahlížet do spouštění, abyste mohli vyhodnotit případná porušení a mít jistotu o platformě.
Následující příklad využívá zásadu verze 1.2 k ověření podrobností o zabezpečeném spouštění, HVCI a Ochrana System Guard Secure Launch. Také ověří, že se během spouštění nenačte nežádoucí ovladač (malicious.sys):
version=1.2;
authorizationrules {
=> permit();
};
issuancerules
{
// Verify if secure boot is enabled
c:[type == "events", issuer=="AttestationService"] => add(type = "efiConfigVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG' && ProcessedData.VariableGuid == '8BE4DF61-93CA-11D2-AA0D-00E098032B8C']"));
c:[type=="efiConfigVariables", issuer=="AttestationPolicy"]=> add(type = "secureBootEnabled", value = JsonToClaimValue(JmesPath(c.value, "[?ProcessedData.UnicodeName == 'SecureBoot'] | length(@) == `1` && @[0].ProcessedData.VariableData == 'AQ'")));
![type=="secureBootEnabled", issuer=="AttestationPolicy"] => add(type="secureBootEnabled", value=false);
// HVCI
c:[type=="events", issuer=="AttestationService"] => add(type="srtmDrtmEventPcr", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `19`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
c:[type=="srtmDrtmEventPcr", issuer=="AttestationPolicy"] => add(type="hvciEnabledSet", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_VBS_HVCI_POLICY | @[?String == 'HypervisorEnforcedCodeIntegrityEnable'].Value")));
c:[type=="hvciEnabledSet", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=ContainsOnlyValue(c.value, 1));
![type=="hvciEnabled", issuer=="AttestationPolicy"] => issue(type="hvciEnabled", value=false);
// Validating unwanted(malicious.sys) driver is not loaded
c:[type=="events", issuer=="AttestationService"] => add(type="boolProperties", value=JmesPath(c.value, "Events[? EventTypeString == 'EV_EVENT_TAG' && (PcrIndex == `12` || PcrIndex == `13` || PcrIndex == `19` || PcrIndex == `20`)].ProcessedData.EVENT_TRUSTBOUNDARY"));
c:[type=="boolProperties", issuer=="AttestationPolicy"] => issue(type="MaliciousDriverLoaded", value=JsonToClaimValue(JmesPath(c.value, "[*].EVENT_LOADEDMODULE_AGGREGATION[] | [? EVENT_IMAGEVALIDATED == true && (equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\malicious.sys') || equals_ignore_case(EVENT_FILEPATH, '\\windows\\system32\\drivers\\wd\\malicious.sys'))] | @ != null ")));
![type=="MaliciousDriverLoaded", issuer=="AttestationPolicy"] => issue(type="MaliciousDriverLoaded", value=false);
};
Rozšíření ochrany před útoky se zlými úmysly prostřednictvím architektury měření integrity (IMA) v Linuxu
Linuxové systémy používají podobný proces spouštění jako Windows a s ověřením čipem TPM je možné rozšířit profil ochrany až po spuštění jádra a také pomocí architektury IMA (Integrity Measurement Architecture). Subsystém IMA byl navržen tak, aby zjistil, jestli nedošlo k náhodnému nebo škodlivému poškození souborů, a to jak vzdáleně, tak místně, udržuje seznam měření modulu runtime, a pokud je ukotvený v hardwarovém čipu Trusted Platform Module (TPM), hodnota agregované integrity nad tímto seznamem poskytuje výhody odolnosti proti softwarovým útokům. Nedávná vylepšení subsystému IMA také umožňují vzdáleně měřit a atestovat atributy, které nejsou založené na souborech. Ověřování identity Azure podporuje vzdáleně atestovaná měření, která nejsou založená na souborech, a poskytuje tak ucelený přehled o integritě systému.
Povolením IMA s následující zásadou ima umožníte měření atributů, které nejsou atributy souborů, a přitom stále povolíte ověření integrity místního souboru.
Pomocí následujících zásad ověření identity teď můžete ověřit secureboot, podpis jádra, verzi jádra, příkazový řádek jádra předaný grubem a další klíčové atributy zabezpečení podporované IMA.
version = 1.2;
configurationrules
{
};
authorizationrules
{
[type == "aikValidated", value==true]
=> permit();
};
issuancerules {
// Retrieve all EFI Boot variables with event = 'EV_EFI_VARIABLE_BOOT'
c:[type == "events", issuer=="AttestationService"] => add(type ="efiBootVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_BOOT']"));
// Retrieve all EFI Driver Config variables with event = 'EV_EFI_VARIABLE_DRIVER_CONFIG'
c:[type == "events", issuer=="AttestationService"] => add(type ="efiConfigVariables", value = JmesPath(c.value, "Events[?EventTypeString == 'EV_EFI_VARIABLE_DRIVER_CONFIG']"));
// Grab all IMA events
c:[type=="events", issuer=="AttestationService"] => add(type="imaMeasurementEvents", value=JmesPath(c.value, "Events[?EventTypeString == 'IMA_MEASUREMENT_EVENT']"));
// Look for "Boot Order" from EFI Boot Data
c:[type == "efiBootVariables", issuer=="AttestationPolicy"] => add(type = "bootOrderFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'BootOrder'] | length(@) == `1` && @[0].PcrIndex == `1` && @[0].ProcessedData.VariableData"));
c:[type=="bootOrderFound", issuer=="AttestationPolicy"] => issue(type="bootOrder", value=JsonToClaimValue(c.value));
![type=="bootOrderFound", issuer=="AttestationPolicy"] => issue(type="bootOrder", value=0);
// Look for "Secure Boot" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => issue(type = "secureBootEnabled", value = JsonToClaimValue(JmesPath(c.value, "[?ProcessedData.UnicodeName == 'SecureBoot'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData == 'AQ'")));
![type=="secureBootEnabled", issuer=="AttestationPolicy"] => issue(type="secureBootEnabled", value=false);
// Look for "Platform Key" from EFI Boot Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "platformKeyFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'PK'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="platformKeyFound", issuer=="AttestationPolicy"] => issue(type="platformKey", value=JsonToClaimValue(c.value));
![type=="platformKeyFound", issuer=="AttestationPolicy"] => issue(type="platformKey", value=0);
// Look for "Key Exchange Key" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "keyExchangeKeyFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'KEK'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="keyExchangeKeyFound", issuer=="AttestationPolicy"] => issue(type="keyExchangeKey", value=JsonToClaimValue(c.value));
![type=="keyExchangeKeyFound", issuer=="AttestationPolicy"] => issue(type="keyExchangeKey", value=0);
// Look for "Key Database" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "keyDatabaseFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'db'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="keyDatabaseFound", issuer=="AttestationPolicy"] => issue(type="keyDatabase", value=JsonToClaimValue(c.value));
![type=="keyDatabaseFound", issuer=="AttestationPolicy"] => issue(type="keyDatabase", value=0);
// Look for "Forbidden Signatures" from EFI Driver Configuration Data
c:[type == "efiConfigVariables", issuer=="AttestationPolicy"] => add(type = "forbiddenSignaturesFound", value = JmesPath(c.value, "[?ProcessedData.UnicodeName == 'dbx'] | length(@) == `1` && @[0].PcrIndex == `7` && @[0].ProcessedData.VariableData"));
c:[type=="forbiddenSignaturesFound", issuer=="AttestationPolicy"] => issue(type="forbiddenSignatures", value=JsonToClaimValue(c.value));
![type=="forbiddenSignaturesFound", issuer=="AttestationPolicy"] => issue(type="forbiddenSignatures", value=0);
// Look for "Kernel Version" in IMA Measurement events
c:[type=="imaMeasurementEvents", issuer=="AttestationPolicy"] => add(type="kernelVersionsFound", value=JmesPath(c.value, "[].ProcessedData.KernelVersion"));
c:[type=="kernelVersionsFound", issuer=="AttestationPolicy"] => issue(type="kernelVersions", value=JsonToClaimValue(c.value));
![type=="kernelVersionsFound", issuer=="AttestationPolicy"] => issue(type="kernelVersions", value=0);
// Look for "Built-In Trusted Keys" in IMA Measurement events
c:[type=="imaMeasurementEvents", issuer=="AttestationPolicy"] => add(type="builtintrustedkeysFound", value=JmesPath(c.value, "[? ProcessedData.Keyring == '.builtin_trusted_keys'].ProcessedData.CertificateSubject"));
c:[type=="builtintrustedkeysFound", issuer=="AttestationPolicy"] => issue(type="builtintrustedkeys", value=JsonToClaimValue(c.value));
![type=="builtintrustedkeysFound", issuer=="AttestationPolicy"] => issue(type="builtintrustedkeys", value=0);
};
Poznámka: Podpora měření, která nejsou založená na souborech, je k dispozici pouze ve verzi jádra Linuxu: 5.15.
Podpora ověření identity pomocí klíče TPM
Mnoho aplikací spoléhá na základní správu přihlašovacích údajů klíčů a certifikátů pro ochranu před krádeží přihlašovacích údajů. Jedním z hlavních způsobů, jak zajistit zabezpečení přihlašovacích údajů, je závislost poskytovatelů úložiště klíčů, kteří poskytují dodatečné zabezpečení před malwarem a útoky. Systém Windows implementuje různé kryptografické zprostředkovatele, které můžou být založené na softwaru nebo hardwaru.
Dva nejdůležitější jsou:
Poskytovatel úložiště softwarových klíčů Microsoftu: Poskytovatel úrovně Standard, který ukládá klíče založené na softwaru a podporuje CNG (Crypto-Next Generation).
Poskytovatel kryptografických služeb Microsoft Platform: Hardware, který ukládá klíče na čipu TPM (modul důvěryhodné platformy) a podporuje také CNG
Při každém použití poskytovatele úložiště se obvykle vytvoří pár klíčů pub/priv, který je zřetězený do kořenového adresáře důvěryhodnosti. Při vytváření lze také použít další vlastnosti k povolení určitých aspektů úložiště klíčů, exportovatelnosti atd. Ověření klíče je v tomto kontextu technická schopnost prokázat straně, která odpovídá, že se privátní klíč vygeneroval uvnitř, spravuje se uvnitř a v neexportovatelné formě. Takové ověření identity s dalšími informacemi může pomoct chránit před krádeží přihlašovacích údajů a před opakovaným útokem.
Čipy TPM také poskytují schopnost osvědčit, že klíče jsou rezidentní v čipu TPM, což umožňuje vyšší záruku zabezpečení, zálohovanou neexportovatelností, anti-hammeringem a izolací klíčů. Běžným případem použití je použití aplikací, které vydávají certifikát digitálního podpisu pro klíče odběratele a ověřují, že je privátní podpisový klíč odběratelů vygenerován a spravován ve schváleném čipu TPM. Pomocí následujících zásad můžete snadno potvrdit, že klíče jsou rezidentní v platném čipu TPM s příslušnými příznaky neexportovatelnosti.
version=1.2;
authorizationrules
{
=> permit();
};
issuancerules
{
// Key Attest Policy
// -- Validating key types
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyType", value=JsonToClaimValue(JmesPath(c.value, "jwk.kty")));
c:[type=="x-ms-tpm-other-keys", issuer=="AttestationService"] => add(type="otherKeysTypes", value=JsonToClaimValue(JmesPath(c.value, "[*].jwk.kty")));
c:[type=="requestKeyType", issuer=="AttestationPolicy", value=="RSA"] => issue(type="requestKeyType", value="RSA");
c:[type=="otherKeysTypes", issuer=="AttestationPolicy", value=="RSA"] => issue(type="otherKeysTypes", value="RSA");
// -- Validating tpm_quote attributes
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyQuote", value=JmesPath(c.value, "info.tpm_quote"));
c:[type=="requestKeyQuote", issuer=="AttestationPolicy"] => add(type="requestKeyQuoteHashAlg", value=JsonToClaimValue(JmesPath(c.value, "hash_alg")));
c:[type=="requestKeyQuoteHashAlg", issuer=="AttestationPolicy", value=="sha-256"] => issue(type="requestKeyQuoteHashAlg", value="sha-256");
// -- Validating tpm_certify attributes
c:[type=="x-ms-tpm-request-key", issuer=="AttestationService"] => add(type="requestKeyCertify", value=JmesPath(c.value, "info.tpm_certify"));
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyNameAlg", value=JsonToClaimValue(JmesPath(c.value, "name_alg")));
c:[type=="requestKeyCertifyNameAlg", issuer=="AttestationPolicy", value==11] => issue(type="requestKeyCertifyNameAlg", value=11);
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyObjAttr", value=JsonToClaimValue(JmesPath(c.value, "obj_attr")));
c:[type=="requestKeyCertifyObjAttr", issuer=="AttestationPolicy", value==50] => issue(type="requestKeyCertifyObjAttr", value=50);
c:[type=="requestKeyCertify", issuer=="AttestationPolicy"] => add(type="requestKeyCertifyAuthPolicy", value=JsonToClaimValue(JmesPath(c.value, "auth_policy")));
c:[type=="requestKeyCertifyAuthPolicy", issuer=="AttestationPolicy", value=="AQIDBA"] => issue(type="requestKeyCertifyAuthPolicy", value="AQIDBA");
c:[type=="x-ms-tpm-other-keys", issuer=="AttestationService"] => add(type="otherKeysCertify", value=JmesPath(c.value, "[*].info.tpm_certify"));
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyNameAlgs", value=JsonToClaimValue(JmesPath(c.value, "[*].name_alg")));
c:[type=="otherKeysCertifyNameAlgs", issuer=="AttestationPolicy", value==11] => issue(type="otherKeysCertifyNameAlgs", value=11);
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyObjAttr", value=JsonToClaimValue(JmesPath(c.value, "[*].obj_attr")));
c:[type=="otherKeysCertifyObjAttr", issuer=="AttestationPolicy", value==50] => issue(type="otherKeysCertifyObjAttr", value=50);
c:[type=="otherKeysCertify", issuer=="AttestationPolicy"] => add(type="otherKeysCertifyAuthPolicy", value=JsonToClaimValue(JmesPath(c.value, "[*].auth_policy")));
c:[type=="otherKeysCertifyAuthPolicy", issuer=="AttestationPolicy", value=="AQIDBA"] => issue(type="otherKeysCertifyAuthPolicy", value="AQIDBA");
};