Features

Diese Seite enthält Informationen zu den kryptografischen Funktionen von Keystore in Android 6.0 und höher.

Kryptographische Primitive

Keystore bietet die folgenden Kategorien von Vorgängen:

  • Schlüsselgenerierung
  • Import und Export von asymmetrischen Schlüsseln (kein Key Wrapping)
  • Import von rohen symmetrischen Schlüsseln (kein Key Wrapping)
  • Asymmetrische Verschlüsselung und Entschlüsselung mit geeigneten Padding-Modi
  • Asymmetrisches Signieren und Verifizieren mit Digesting und geeigneten Padding-Modi
  • Symmetrische Verschlüsselung und Entschlüsselung in geeigneten Modi, einschließlich eines AEAD-Modus
  • Generierung und Überprüfung von symmetrischen Nachrichtenauthentifizierungscodes

Protokollelemente wie Zweck, Modus und Auffüllen sowie Zugriffskontrollbeschränkungen werden beim Generieren oder Importieren von Schlüsseln festgelegt und dauerhaft an den Schlüssel gebunden, um sicherzustellen, dass der Schlüssel nicht anderweitig verwendet werden kann.

Zusätzlich zu der obigen Liste gibt es einen weiteren Dienst, den Keymaster-Implementierungen bereitstellen, der jedoch nicht als API verfügbar gemacht wird: Generierung von Zufallszahlen. Dies wird intern zum Generieren von Schlüsseln, Initialisierungsvektoren (IVs), zufälligem Auffüllen und anderen Elementen sicherer Protokolle verwendet, die Zufälligkeit erfordern.

Notwendige Primitive

Alle Keymaster-Implementierungen bieten:

  • RSA
    • 2048-, 3072- und 4096-Bit-Schlüsselunterstützung
    • Unterstützung für den öffentlichen Exponenten F4 (2^16+1)
    • Auffüllmodi für RSA-Signaturen:
      • RSASSA-PSS ( PaddingMode::RSA_PSS )
      • RSASSA-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_SIGN )
    • Digest-Modi für RSA-Signaturen:
      • SHA-256
    • Padding-Modi für RSA-Verschlüsselung/-Entschlüsselung:
      • Ungepolstert
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • 224-, 256-, 384- und 521-Bit-Schlüsselunterstützung werden unterstützt, wobei die Kurven NIST P-224, P-256, P-384 bzw. P-521 verwendet werden
    • Digest-Modi für ECDSA:
      • Kein Digest (veraltet, wird in Zukunft entfernt)
      • SHA-256
  • AES
    • 128- und 256-Bit-Schlüssel werden unterstützt
    • CBC , CTR, EZB und GCM. Die GCM-Implementierung erlaubt keine Verwendung von Tags, die kleiner als 96 Bit sind, oder von anderen Nonce-Längen als 96 Bit.
    • PaddingMode::NONE PaddingMode::NONE und PaddingMode::PKCS7 werden für CBC- und ECB-Modi unterstützt. Ohne Padding schlägt die Verschlüsselung im CBC- oder ECB-Modus fehl, wenn die Eingabe kein Vielfaches der Blockgröße ist.
  • HMAC SHA-256 , mit beliebiger Schlüsselgröße bis mindestens 32 Byte.

SHA1 und die anderen Mitglieder der SHA2-Familie (SHA-224, SHA384 und SHA512) werden für Keymaster-Implementierungen dringend empfohlen. Keystore stellt sie in Software bereit, wenn die Hardware-Keymaster-Implementierung sie nicht bereitstellt.

Einige Grundelemente werden auch für die Interoperabilität mit anderen Systemen empfohlen:

  • Kleinere Schlüsselgrößen für RSA
  • Willkürliche öffentliche Exponenten für RSA

Schlüsselzugangskontrolle

Hardwarebasierte Schlüssel, die niemals aus dem Gerät extrahiert werden können, bieten nicht viel Sicherheit, wenn ein Angreifer sie nach Belieben verwenden kann (obwohl sie sicherer sind als Schlüssel, die exfiltriert werden können ). Daher ist es entscheidend, dass Keystore Zugriffskontrollen durchsetzt.

Zugriffskontrollen sind als "Autorisierungsliste" von Tag/Wert-Paaren definiert. Autorisierungs-Tags sind 32-Bit-Ganzzahlen und die Werte sind eine Vielzahl von Typen. Einige Tags können wiederholt werden, um mehrere Werte anzugeben. Ob ein Tag wiederholt werden darf, ist in der Dokumentation zum Tag angegeben. Wenn ein Schlüssel erstellt wird, gibt der Aufrufer eine Berechtigungsliste an. Die Keymaster-Implementierung, die Keystore zugrunde liegt, ändert die Liste, um einige zusätzliche Informationen anzugeben, z. B. ob der Schlüssel über einen Rollback-Schutz verfügt, und gibt eine "endgültige" Autorisierungsliste zurück, die in das zurückgegebene Schlüssel-Blob codiert ist. Jeder Versuch, den Schlüssel für eine kryptografische Operation zu verwenden, schlägt fehl, wenn die endgültige Autorisierungsliste geändert wird.

Für Keymaster 2 und früher ist der Satz möglicher Tags in der Enumeration keymaster_authorization_tag_t definiert und dauerhaft festgelegt (obwohl er erweitert werden kann). Den Namen wurde KM_TAG vorangestellt. Die obersten vier Bits der Tag-IDs werden verwendet, um den Typ anzuzeigen.

Keymaster 3 hat das Präfix KM_TAG in Tag:: geändert.

Mögliche Typen sind:

ENUM : Die Werte vieler Tags werden in Aufzählungen definiert. Beispielsweise sind die möglichen Werte von TAG::PURPOSE in enum keymaster_purpose_t definiert.

ENUM_REP : Wie ENUM , außer dass das Tag in einer Berechtigungsliste wiederholt werden darf. Wiederholung zeigt mehrere autorisierte Werte an. Beispielsweise hat ein Verschlüsselungsschlüssel wahrscheinlich KeyPurpose::ENCRYPT und KeyPurpose::DECRYPT .

UINT : 32-Bit-Ganzzahlen ohne Vorzeichen. Beispiel: TAG::KEY_SIZE

UINT_REP : Dasselbe wie UINT , außer dass das Tag in einer Autorisierungsliste wiederholt werden kann. Wiederholung zeigt mehrere autorisierte Werte an.

ULONG : 64-Bit-Ganzzahlen ohne Vorzeichen. Beispiel: TAG::RSA_PUBLIC_EXPONENT

ULONG_REP : Wie ULONG , außer dass das Tag in einer Autorisierungsliste wiederholt werden kann. Wiederholung zeigt mehrere autorisierte Werte an.

DATE : Datums-/Zeitwerte, ausgedrückt als Millisekunden seit dem 1. Januar 1970. Beispiel: TAG::PRIVKEY_EXPIRE_DATETIME

BOOL : Wahr oder falsch. Ein Tag vom Typ BOOL wird als „falsch“ angenommen, wenn das Tag nicht vorhanden ist, und als „wahr“, wenn es vorhanden ist. Beispiel: TAG::ROLLBACK_RESISTANT

BIGNUM : Ganzzahlen beliebiger Länge, ausgedrückt als Byte-Array in Big-Endian-Reihenfolge. Beispiel: TAG::RSA_PUBLIC_EXPONENT

BYTES : Eine Folge von Bytes. Beispiel: TAG::ROOT_OF_TRUST

Hardware- vs. Softwaredurchsetzung

Nicht alle sicheren Hardwareimplementierungen enthalten die gleichen Funktionen. Um eine Vielzahl von Ansätzen zu unterstützen, unterscheidet Keymaster zwischen der Durchsetzung der sicheren und nicht sicheren Weltzugangskontrolle bzw. der Hardware- und Softwaredurchsetzung.

Alle Implementierungen:

  • Exakte Übereinstimmung (nicht Erzwingung) aller Autorisierungen erzwingen. Autorisierungslisten in Schlüssel-Blobs stimmen genau mit den Autorisierungen überein, die während der Schlüsselgenerierung zurückgegeben werden, einschließlich der Reihenfolge. Jede Nichtübereinstimmung führt zu einer Fehlerdiagnose.
  • Deklarieren Sie die Berechtigungen, deren semantische Werte erzwungen werden.

Der API-Mechanismus zum Deklarieren von Hardware-erzwungenen Autorisierungen befindet sich in der keymaster_key_characteristics_t -Struktur. Es teilt die Autorisierungsliste in zwei Unterlisten, hw_enforced und sw_enforced . Die sichere Hardware ist dafür verantwortlich, die entsprechenden Werte in jedem zu platzieren, basierend auf dem, was sie durchsetzen kann.

Darüber hinaus implementiert Keystore eine softwarebasierte Durchsetzung aller Autorisierungen, unabhängig davon, ob sie von der sicheren Hardware durchgesetzt werden oder nicht.

Betrachten Sie beispielsweise eine TrustZone-basierte Implementierung, die keinen Schlüsselablauf unterstützt. Ein Schlüssel mit einem Ablaufdatum kann dennoch erstellt werden. Die Autorisierungsliste dieses Schlüssels enthält das Tag TAG::ORIGINATION_EXPIRE_DATETIME mit dem Ablaufdatum. Eine Anforderung an Keystore für die Schlüsselmerkmale findet dieses Tag in der sw_enforced Liste und die sichere Hardware erzwingt die Ablaufanforderung nicht. Versuche, den Schlüssel nach Ablauf zu verwenden, werden jedoch von Keystore zurückgewiesen.

Wenn das Gerät dann mit sicherer Hardware aktualisiert wird, die den Ablauf unterstützt, findet eine Anfrage nach Schlüsselmerkmalen TAG::ORIGINATION_EXPIRE_DATETIME in der hw_enforced Liste, und Versuche, den Schlüssel nach Ablauf zu verwenden, schlagen fehl, selbst wenn der Schlüsselspeicher irgendwie untergraben oder umgangen wird .

Weitere Informationen zum Ermitteln, ob Schlüssel hardwaregestützt sind, finden Sie unter Schlüsselnachweis .

Berechtigungen zum Aufbau kryptografischer Nachrichten

Die folgenden Tags werden verwendet, um die kryptografischen Merkmale von Operationen unter Verwendung des zugehörigen Schlüssels zu definieren: TAG::ALGORITHM , TAG::KEY_SIZE , TAG::BLOCK_MODE , TAG::PADDING , TAG::CALLER_NONCE und TAG::DIGEST

TAG::PADDING , TAG::DIGEST und PaddingMode::BLOCK_MODE sind wiederholbar, was bedeutet, dass mehrere Werte mit einem einzigen Schlüssel verknüpft werden können und der zu verwendende Wert zum Zeitpunkt der Operation angegeben wird.

Zweck

Schlüssel haben einen zugeordneten Satz von Zwecken, ausgedrückt als ein oder mehrere Autorisierungseinträge mit dem Tag TAG::PURPOSE , das definiert, wie sie verwendet werden können. Die Zwecke sind:

  • KeyPurpose::ENCRYPT
  • KeyPurpose::DECRYPT
  • KeyPurpose::SIGN
  • KeyPurpose::VERIFY

Jeder Schlüssel kann eine beliebige Teilmenge dieser Zwecke haben. Beachten Sie, dass einige Kombinationen Sicherheitsprobleme verursachen. Beispielsweise ermöglicht ein RSA-Schlüssel, der sowohl zum Verschlüsseln als auch zum Signieren verwendet werden kann, einem Angreifer, der das System dazu verleiten kann, beliebige Daten zu entschlüsseln, um Signaturen zu generieren.

Import und Export

Keymaster unterstützt nur den Export öffentlicher Schlüssel im X.509-Format und den Import von:

  • Öffentliche und private Schlüsselpaare im DER-codierten PKCS#8-Format, ohne passwortbasierte Verschlüsselung
  • Symmetrische Schlüssel als Rohbytes

Damit importierte Schlüssel von sicher generierten Schlüsseln unterschieden werden können, wird TAG::ORIGIN in die entsprechende Schlüsselberechtigungsliste aufgenommen. Wenn beispielsweise ein Schlüssel in sicherer Hardware generiert wurde, wird TAG::ORIGIN mit dem Wert KeyOrigin::GENERATED in der hw_enforced Liste der Schlüsselmerkmale gefunden, während ein Schlüssel, der in sichere Hardware importiert wurde, den Wert KeyOrigin::IMPORTED .

Benutzerauthentifizierung

Sichere Keymaster-Implementierungen implementieren keine Benutzerauthentifizierung, sondern sind von anderen vertrauenswürdigen Apps abhängig, die dies tun. Informationen zur Schnittstelle, die diese Apps implementieren, finden Sie auf der Gatekeeper-Seite .

Benutzerauthentifizierungsanforderungen werden über zwei Sätze von Tags angegeben. Der erste Satz gibt an, welcher Benutzer den Schlüssel verwenden kann:

  • TAG::ALL_USERS gibt an, dass der Schlüssel von allen Benutzern verwendet werden kann. Falls vorhanden, TAG::USER_ID und TAG::USER_SECURE_ID ist nicht vorhanden.
  • TAG::USER_ID hat einen numerischen Wert, der die ID des autorisierten Benutzers angibt. Beachten Sie, dass dies die Android-Benutzer-ID (für mehrere Benutzer) und nicht die Anwendungs-UID ist und nur von nicht sicherer Software erzwungen wird. Falls vorhanden, ist TAG::ALL_USERS nicht vorhanden.
  • TAG::USER_SECURE_ID hat einen numerischen 64-Bit-Wert, der die sichere Benutzer-ID angibt, die in einem sicheren Authentifizierungstoken bereitgestellt wird, um die Verwendung des Schlüssels zu entsperren. Bei Wiederholung kann der Schlüssel verwendet werden, wenn einer der Werte in einem sicheren Authentifizierungstoken bereitgestellt wird.

Der zweite Satz gibt an, ob und wann der Benutzer authentifiziert werden muss. Wenn keines dieser Tags vorhanden ist, TAG::USER_SECURE_ID jedoch vorhanden ist, ist für jede Verwendung des Schlüssels eine Authentifizierung erforderlich.

  • NO_AUTHENTICATION_REQUIRED gibt an, dass keine Benutzerauthentifizierung erforderlich ist, obwohl der Schlüssel weiterhin nur von Apps verwendet werden kann, die als die durch TAG::USER_ID angegebenen Benutzer ausgeführt werden.
  • TAG::AUTH_TIMEOUT ist ein numerischer Wert, der in Sekunden angibt, wie frisch die Benutzerauthentifizierung sein muss, um die Schlüsselverwendung zu autorisieren. Dies gilt nur für Operationen mit privaten/geheimen Schlüsseln. Public-Key-Operationen erfordern keine Authentifizierung. Timeouts wirken sich nicht auf Neustarts aus; Nach einem Neustart werden alle Schlüssel "nie authentifiziert". Das Timeout kann auf einen hohen Wert eingestellt werden, um anzuzeigen, dass die Authentifizierung einmal pro Start erforderlich ist (2^32 Sekunden sind ~136 Jahre; vermutlich werden Android-Geräte häufiger neu gestartet).

Mandantenbindung

Die Clientbindung, die Zuordnung eines Schlüssels zu einer bestimmten Clientanwendung, erfolgt über eine optionale Client-ID und einige optionale Clientdaten ( TAG::APPLICATION_ID bzw. TAG::APPLICATION_DATA ). Keystore behandelt diese Werte als undurchsichtige Blobs und stellt nur sicher, dass dieselben Blobs, die während der Schlüsselgenerierung/des Imports präsentiert werden, für jede Verwendung präsentiert werden und Byte für Byte identisch sind. Die Clientbindungsdaten werden nicht von Keymaster zurückgegeben. Der Anrufer muss sie kennen, um die Taste verwenden zu können.

Diese Funktion ist für Anwendungen nicht verfügbar.

Ablauf

Keystore unterstützt die Einschränkung der Schlüsselnutzung nach Datum. Schlüsselgültigkeitsbeginn und Schlüsselablauf können einem Schlüssel zugeordnet werden und Keymaster verweigert Schlüsseloperationen, wenn das aktuelle Datum/die aktuelle Uhrzeit außerhalb des gültigen Bereichs liegt. Der Schlüsselgültigkeitsbereich wird mit den Tags TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIME und TAG::USAGE_EXPIRE_DATETIME . Die Unterscheidung zwischen „Ursprung“ und „Verwendung“ basiert darauf, ob der Schlüssel verwendet wird, um einen neuen Chiffretext/Signatur/etc. Beachten Sie, dass diese Unterscheidung nicht für Anwendungen verfügbar ist.

Die Tags TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIME und TAG::USAGE_EXPIRE_DATETIME sind optional. Wenn die Tags fehlen, wird davon ausgegangen, dass der betreffende Schlüssel immer zum Entschlüsseln/Verifizieren von Nachrichten verwendet werden kann.

Da die Uhrzeit von der nicht sicheren Welt bereitgestellt wird, ist es unwahrscheinlich, dass die ablaufbezogenen Tags in der hardwareerzwungenen Liste enthalten sind. Die Hardwaredurchsetzung des Ablaufs würde erfordern, dass die sichere Welt irgendwie vertrauenswürdige Zeit und Daten erhält, beispielsweise über ein Challenge-Response-Protokoll mit einem vertrauenswürdigen Remote-Zeitserver.

Root-of-Trust-Bindung

Keystore erfordert, dass Schlüssel an einen Root of Trust gebunden werden, bei dem es sich um eine Bitfolge handelt, die der sicheren Keymaster-Hardware während des Starts bereitgestellt wird, vorzugsweise vom Bootloader. Diese Bitfolge ist kryptografisch an jeden von Keymaster verwalteten Schlüssel gebunden.

Der Vertrauensanker besteht aus dem öffentlichen Schlüssel, der verwendet wird, um die Signatur auf dem Boot-Image und dem Sperrstatus des Geräts zu überprüfen. Wenn der öffentliche Schlüssel geändert wird, damit ein anderes Systemabbild verwendet werden kann, oder wenn der Sperrstatus geändert wird, ist keiner der Keymaster-geschützten Schlüssel, die vom vorherigen System erstellt wurden, verwendbar, es sei denn, der vorherige Vertrauensanker wird wiederhergestellt und ein System das mit diesem Schlüssel signiert ist, wird gebootet. Ziel ist es, den Wert der durch Software erzwungenen Schlüsselzugriffskontrollen zu erhöhen, indem es einem von einem Angreifer installierten Betriebssystem unmöglich gemacht wird, Keymaster-Schlüssel zu verwenden.

Eigenständige Schlüssel

Einige sichere Hardware von Keymaster entscheidet sich möglicherweise dafür, Schlüsselmaterial intern zu speichern und Handles anstelle von verschlüsseltem Schlüsselmaterial zurückzugeben. Oder es kann andere Fälle geben, in denen Schlüssel nicht verwendet werden können, bis eine andere nicht sichere oder sichere Weltsystemkomponente verfügbar ist. Die Keymaster-HAL ermöglicht es dem Anrufer, über das TAG::STANDALONE -Tag anzufordern, dass ein Schlüssel "eigenständig" ist, was bedeutet, dass keine anderen Ressourcen als das Blob und das laufende Keymaster-System erforderlich sind. Die einem Schlüssel zugeordneten Tags können überprüft werden, um festzustellen, ob ein Schlüssel eigenständig ist. Derzeit sind nur zwei Werte definiert:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Diese Funktion ist für Anwendungen nicht verfügbar.

Geschwindigkeit

Beim Erstellen kann die maximale Nutzungsgeschwindigkeit mit TAG::MIN_SECONDS_BETWEEN_OPS angegeben werden. TrustZone-Implementierungen verweigern kryptografische Operationen mit diesem Schlüssel, wenn eine Operation weniger als TAG::MIN_SECONDS_BETWEEN_OPS Sekunden zuvor durchgeführt wurde.

Der einfache Ansatz zur Implementierung von Geschwindigkeitsbegrenzungen ist eine Tabelle mit Schlüssel-IDs und Zeitstempeln der letzten Verwendung. Diese Tabelle wird wahrscheinlich eine begrenzte Größe haben, aber mindestens 16 Einträge aufnehmen. Für den Fall, dass die Tabelle voll ist und keine Einträge aktualisiert oder verworfen werden können, sichern Hardwareimplementierungen "ausfallsicher", indem sie es vorziehen, alle geschwindigkeitsbegrenzten Tastenoperationen abzulehnen, bis einer der Einträge abläuft. Es ist akzeptabel, dass alle Einträge beim Neustart ablaufen.

Schlüssel können auch mit TAG::MAX_USES_PER_BOOT auf n Verwendungen pro Boot beschränkt werden. Dazu braucht es auch einen Tracking-Tisch, der mindestens vier Schlüssel aufnimmt und zudem ausfallsicher ist. Beachten Sie, dass Anwendungen keine pro Boot begrenzten Schlüssel erstellen können. Diese Funktion wird nicht über Keystore verfügbar gemacht und ist für Systemoperationen reserviert.

Diese Funktion ist für Anwendungen nicht verfügbar.

Reseeding des Zufallszahlengenerators

Da sichere Hardware Zufallszahlen für Schlüsselmaterial und Initialisierungsvektoren (IVs) generiert und da Hardware-Zufallszahlengeneratoren möglicherweise nicht immer vollständig vertrauenswürdig sind, bietet der Keymaster HAL eine Schnittstelle, die es dem Client ermöglicht, zusätzliche Entropie bereitzustellen, die in den Zufall gemischt wird Zahlen generiert.

Verwenden Sie einen Hardware-Zufallszahlengenerator als primäre Seed-Quelle. Die über die externe API bereitgestellten Seed-Daten können nicht die einzige Zufallsquelle sein, die für die Nummerngenerierung verwendet wird. Ferner muss die verwendete Mischoperation sicherstellen, dass die zufällige Ausgabe unvorhersagbar ist, wenn eine der Seed-Quellen unvorhersehbar ist.

Diese Funktion ist nicht für Anwendungen verfügbar, wird aber vom Framework verwendet, das regelmäßig zusätzliche Entropie, die von einer Java SecureRandom-Instanz abgerufen wird, für die sichere Hardware bereitstellt.