Delen via


Attestation van trusted Platform-module

Apparaten met een TPM (Trusted Platform Module) kunnen afhankelijk zijn van attestation om te bewijzen dat de opstartintegriteit niet wordt aangetast, samen met het gemeten opstartproces om vroege statussen van opstartfuncties te detecteren.

Voor een groeiend aantal apparaattypen, bootloaders en opstartstackaanvallen is een attestation-oplossing vereist om dienovereenkomstig te ontwikkelen. Een geteste status van een apparaat wordt aangestuurd door het attestation-beleid dat wordt gebruikt om de inhoud van het platformbewijs te verifiëren.

Dit artikel bevat een overzicht van TPM-attestation en mogelijkheden die worden ondersteund door Azure Attestation.

Overzicht

TPM-attestation begint met het valideren van de TPM zelf tot aan het punt waar een relying party de opstartstroom kan valideren.

Over het algemeen is TPM-attestation gebaseerd op de volgende pijlers.

TPM-echtheid valideren

Valideer de TPM-echtheid door de TPM te valideren:

  • Elke TPM wordt geleverd met een unieke asymmetrische sleutel, de goedkeuringssleutel (EK) genoemd. Deze sleutel wordt door de fabrikant verbrand. Het openbare gedeelte van deze sleutel wordt EKPub genoemd. De bijbehorende persoonlijke sleutel wordt EKPriv genoemd. Sommige TPM-chips hebben ook een EK-certificaat dat is uitgegeven door de fabrikant voor de EKPub. Dit certificaat wordt EKCert genoemd.
  • Een certificeringsinstantie (CA) stelt een vertrouwensrelatie in de TPM in via EKPub of EKCert.
  • Een apparaat bewijst aan de CA dat de sleutel waarvoor het certificaat wordt aangevraagd cryptografisch is gebonden aan de EKPub en dat de TPM eigenaar is van de EKPriv.
  • De CA geeft een certificaat uit met een speciaal uitgiftebeleid om aan te geven dat de sleutel nu wordt getest als beveiligd door een TPM.

De metingen valideren die tijdens het opstarten zijn uitgevoerd

Valideer de metingen die tijdens het opstarten zijn uitgevoerd met behulp van Azure Attestation:

  • Als onderdeel van Trusted Boot en Measured Boot wordt elke stap gevalideerd en gemeten in de TPM. Verschillende gebeurtenissen worden gemeten voor verschillende platforms. Zie Het Windows-opstartproces beveiligen voor meer informatie over het gemeten opstartproces in Windows.
  • Bij het opstarten wordt een attestation-identiteitssleutel gegenereerd. Het wordt gebruikt om cryptografisch bewijs te leveren aan de attestation-service dat de TPM die wordt gebruikt, een certificaat heeft uitgegeven nadat de EK-validatie is uitgevoerd.
  • Relying party's kunnen een attestation uitvoeren op Basis van Azure Attestation, die kan worden gebruikt om metingen te valideren die tijdens het opstartproces zijn uitgevoerd.
  • Een relying party kan vervolgens vertrouwen op de attestation-instructie om toegang tot resources of andere acties te gaten.

Diagram met de conceptuele attestation-stroom voor apparaten.

Tpm-attestation kan conceptueel worden gevisualiseerd, zoals wordt weergegeven in het voorgaande diagram. De relying party past Azure Attestation toe om de integriteit van het platform en eventuele schendingen van beloftes te verifiëren. Het verificatieproces geeft u het vertrouwen om workloads uit te voeren of toegang te bieden tot resources.

Bescherming tegen schadelijke opstartaanvallen

Volwassen aanvalstechnieken zijn gericht op het infecteren van de opstartketen. Een opstartaanval kan de aanvaller toegang bieden tot systeembronnen en de aanvaller toestaan zich te verbergen voor antimalwaresoftware. Trusted Boot fungeert als de eerste verdedigingsvolgorde. Het gebruik van Trusted Boot en attestation breidt de mogelijkheid uit naar relying party's. De meeste aanvallers proberen beveiligd opstarten te omzeilen of een ongewenst binair bestand in het opstartproces te laden.

Met Remote Attestation kunnen de relying party's de hele opstartketen controleren op elke schending van beloftes. De evaluatie van beveiligd opstarten door de attestation-service valideert bijvoorbeeld de waarden van de beveiligde variabelen die worden gemeten door UEFI.

Meting boot-instrumentatie zorgt ervoor dat cryptografisch gebonden metingen niet kunnen worden gewijzigd nadat ze zijn gemaakt en dat alleen een vertrouwd onderdeel de meting kan maken. Daarom is het valideren van de beveiligde variabelen voldoende om de activering te garanderen.

Azure Attestation ondertekent het rapport om ervoor te zorgen dat de integriteit van de attestation ook wordt gehandhaafd om te beschermen tegen man-in-the-middle-aanvallen.

Een eenvoudig beleid kan worden gebruikt:

version=1.0;

authorizationrules { 
    => permit();
};


issuancerules
{
[type=="aikValidated", value==true] && 
[type=="secureBootEnabled", value==true] => issue(type="PlatformAttested", value=true);
};

Soms is het niet voldoende om slechts één onderdeel in het opstarten te verifiëren. Het controleren van aanvullende functies zoals code-integriteit of met hypervisor beschermde code-integriteit (HVCI) en System Guard Secure Launch voegt toe aan het beveiligingsprofiel van een apparaat. U hebt ook de mogelijkheid nodig om te peeren met het opstarten, zodat u eventuele schendingen kunt evalueren en vertrouwen hebt in het platform.

In het volgende voorbeeld wordt gebruikgemaakt van beleidsversie 1.2 om details te controleren over beveiligd opstarten, HVCI en System Guard Secure Launch. Er wordt ook gecontroleerd of een ongewenst stuurprogramma (malicious.sys) niet wordt geladen tijdens het opstarten:

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);

};

De beveiliging tegen schadelijke opstartaanvallen uitbreiden via Integrity Measurement Architecture (IMA) in Linux

Linux-systemen volgen een vergelijkbaar opstartproces met Windows en met TPM-attestation kan het beveiligingsprofiel worden uitgebreid naar buiten opstarten in de kernel en met behulp van Integriteitsmetingsarchitectuur (IMA). Het IMA-subsysteem is ontworpen om te detecteren of bestanden per ongeluk of kwaadwillend zijn gewijzigd, zowel extern als lokaal, het onderhoudt een lijst met runtimemetingen en, indien verankerd in een hardware Trusted Platform Module (TPM), een cumulatieve integriteitswaarde voor deze lijst biedt het voordeel van tolerantie van softwareaanvallen. Recente verbeteringen in het IMA-subsysteem zorgen er ook voor dat niet-bestandskenmerken op afstand kunnen worden gemeten en getest. Azure Attestation biedt ondersteuning voor niet-bestandsgebaseerde metingen die extern moeten worden getest om een holistische weergave van systeemintegriteit te bieden.

Als u IMA inschakelt met het volgende ima-beleid, wordt het meten van niet-bestandskenmerken ingeschakeld terwijl nog steeds lokale attestation voor bestandsintegriteit wordt ingeschakeld.

Met behulp van het volgende Attestation-beleid kunt u nu de secureboot, kernelhandtekening, kernelversie, kernel-cmdline valideren die wordt doorgegeven door grub en andere sleutelbeveiligingskenmerken die worden ondersteund door 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);
};

Opmerking: ondersteuning voor niet-bestandsgebaseerde metingen is alleen beschikbaar via linux-kernelversie: 5.15

Ondersteuning voor TPM-sleutelattest

Talloze toepassingen zijn afhankelijk van basisreferentiebeheer van sleutels en certificaten voor beveiliging tegen diefstal van referenties, en een van de belangrijkste manieren om ervoor te zorgen dat de referentiebeveiliging de vertrouwensrelatie is van sleutelopslagproviders die extra beveiliging bieden tegen malware en aanvallen. Windows implementeert verschillende cryptografische providers die software of hardware kunnen zijn.

De twee belangrijkste zijn:

  • Microsoft Software Key Storage Provider: Standard-provider, die sleutels op basis van software opslaat en CNG ondersteunt (Crypto-Next Generation)

  • Microsoft Platform Crypto Provider: Hardware gebaseerd die sleutels opslaat op een TPM (trusted platform module) en ondersteunt ook CNG

Wanneer een opslagprovider wordt gebruikt, is het meestal om een pub/priv-sleutelpaar te maken dat is gekoppeld aan een basis van vertrouwen. Bij het maken van meer eigenschappen kan ook worden gebruikt om bepaalde aspecten van de sleutelopslag, exportbaarheid, enzovoort mogelijk te maken. Sleutelverklaring in deze context is de technische mogelijkheid om aan een antwoordpartij te bewijzen dat er een persoonlijke sleutel is gegenereerd en wordt beheerd binnen en in een niet-exporteerbare vorm. Dergelijke attestation-clubbed met andere informatie kan helpen beschermen tegen referentiediefstal en type aanval.

TPM's bieden ook de mogelijkheid om te bevestigen dat sleutels zich in een TPM bevinden, waardoor een hogere beveiligingsgarantie mogelijk is, waarvan een back-up wordt gemaakt door niet-exporteerbaarheid, antihamers en isolatie van sleutels. Een veelvoorkomende use-case is voor toepassingen die een digitaal handtekeningcertificaat uitgeven voor abonneesleutels, waarbij wordt gecontroleerd of de persoonlijke handtekeningsleutel van abonnees wordt gegenereerd en beheerd in een goedgekeurde TPM. U kunt eenvoudig bevestigen dat de sleutels zich in een geldige TPM bevinden met de juiste vlaggen voor niet-exporteerbaarheid met behulp van een beleid zoals hieronder.

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");
};

Volgende stappen