Ich habe Marshmallow gerade über ein Push-Update auf einem Nexus 5 installiert. Ich bin verwirrt über die Funktionsweise der Verschlüsselung. Ich habe gute technische Kenntnisse der Verschlüsselung auf Computern. Ich möchte ähnliche Kenntnisse über Android 6 erlangen.
Das Folgende ist, was ich getan habe und wie ich verwirrt wurde. Nach einem Factory Reset habe ich eine PIN eingerichtet und das Gerät dann verschlüsselt. Beim Booten wurde ich nach meiner PIN gefragt, was erwartet wurde. Ich habe dann die PIN entfernt und das Gerät neu gestartet. Beim Booten wurde keine PIN abgefragt, das Gerät hat sich jedoch im Setup-Menü als verschlüsselt gemeldet. Letzteres verwirrt mich, da ich erwartet habe, dass die PIN den Entschlüsselungsschlüssel entsperrt.
Fragen:
- Woher kommt der Entschlüsselungsschlüssel bei einer Verschlüsselung ohne PIN? Ich gehe davon aus, dass es auf einem Chip ähnlich einem TPM gespeichert ist. Ist das richtig? Wenn ja, was hindert einen Hacker daran, diesen Schlüssel vom Chip anzufordern? Überprüft es den Hash der Firmware? Noch etwas? Technische Details wären sehr dankbar.
- Wird bei der Verschlüsselung mit einer PIN die PIN als zusätzliches Token für den Zugriff auf den Entschlüsselungsschlüssel verwendet? Oder funktioniert der Entschlüsselungsprozess genau so, als ob keine PIN vorhanden wäre.
TL; DL Antwort:
Der Entschlüsselungsschlüssel wird mit allen folgenden Funktionen entsperrt:
- Die PIN (oder das Kennwort usw.) oder ein Standardkennwort, falls keines vorhanden ist
- Ein TEE (ein Hardware-unterstützter Signaturgenerator, der Schlüssel verwendet, die nicht extrahiert werden können)
- Ein Salz (leicht verfügbar, verhindert jedoch Angriffe durch Regenbogentabellen)
quelle
Antworten:
Ich zitiere aus dem Android - Handbuch hier , aber:
HINWEIS:
Die Quelle, die ich verwendet habe, ist nicht direkt relevant für Marshmallow, sondern für Lollipop und höher.
TL: DR
Ich werde jetzt nur die Fragen des OP ansprechen. Technische Details folgen.
Der Standard - Verschlüsselungsschlüssel stammt aus einer Hardware - Quelle (ein Chip ähnlich einen TPM) und das Standardkennwort AOSP definiert als
default_password
in dercryptfs.c
Quelldatei, siehe unten.Ja, nicht nur die Standardeinstellung, sondern jedes Passwort wird in einen Schlüssel umgewandelt und auf einem TPM-ähnlichen Chip gespeichert, der als TEE (kurz für "Trusted Execution Environment", siehe unten für weitere Details) bezeichnet wird.
Ein Hacker mit UART / JTAG-Zugriff auf die Chips auf dem SoC des Geräts kann technisch Zugriff auf den TEE-Schlüssel erhalten, oder ein benutzerdefinierter Kernel kann diese Informationen an einen Hacker weitergeben. Einige 3-Buchstaben-Agenturen in Verschwörungstheorien können möglicherweise mit dem OEM zusammenarbeiten, um diese unsicheren Kernel für Produktionsgeräte zu verwenden, aber ich würde nicht viele Geschäfte damit abschließen. Weitere Einzelheiten finden Sie im letzten Abschnitt dieser Antwort.
Das Einzige, was einen Hacker daran hindert, auf den Schlüssel zuzugreifen, ist der schiere Aufwand, der dafür erforderlich ist.
dm-verity
. Dies ist jedoch unabhängig vom Verschlüsselungsstatus.Quelle: AOSP-Sicherheitsleitfaden hier .
Überblick
Beim ersten Start erstellt das Gerät einen zufällig generierten 128-Bit-Hauptschlüssel und hasht ihn dann mit einem Standardkennwort und gespeichertem Salt. Das Standardkennwort lautet: "default_password" Der resultierende Hash wird jedoch auch über ein TEE (z. B. TrustZone) signiert, das einen Hash der Signatur zum Verschlüsseln des Hauptschlüssels verwendet.
Das Standardkennwort finden Sie in der Datei cryptfs.c des Android Open Source-Projekts .
Wenn der Benutzer die PIN / Pass oder das Passwort für das Gerät festlegt, wird nur der 128-Bit-Schlüssel neu verschlüsselt und gespeichert. (Das heißt, Benutzer-PIN- / Pass- / Musteränderungen verursachen KEINE Neuverschlüsselung der Benutzerdatenpartition.)
Starten eines verschlüsselten Geräts mit Standardverschlüsselung
Dies passiert, wenn Sie ein verschlüsseltes Gerät ohne Kennwort starten. Da Android 5.0-Geräte beim ersten Start verschlüsselt werden, sollte kein Kennwort festgelegt sein. Daher ist dies der Standardverschlüsselungsstatus.
Erkennen Sie, dass das Android-Gerät verschlüsselt ist, weil / data nicht bereitgestellt werden kann und eines der Flags
encryptable
oderforceencrypt
gesetzt ist.vold
setztvold.decrypt
auftrigger_default_encryption
, was dendefaultcrypto
Dienst startet .trigger_default_encryption
Überprüft den Verschlüsselungstyp, um festzustellen, ob / data mit oder ohne Kennwort verschlüsselt ist.Erstellt das
dm-crypt
Gerät über dem Blockgerät, sodass das Gerät einsatzbereit ist.vold
Mounten Sie dann die entschlüsselte Real- / Datenpartition und bereiten Sie die neue Partition vor. Es setzt die Eigenschaftvold.post_fs_data_done
auf0
und setzt dannvold.decrypt
auftrigger_post_fs_data
. Dies bewirkt , dassinit.rc
seine laufenpost-fs-data
Befehle. Sie erstellen alle erforderlichen Verzeichnisse oder Links und setzen sie dannvold.post_fs_data_done
auf1
.Sobald
vold
die 1 in dieser Eigenschaft sieht, setzt es die Eigenschaftvold.decrypt
auf:trigger_restart_framework
. Dies führtinit.rc
dazu, dass Dienste in der Klassemain
erneut gestartet werden und Dienste in der Klasse late_start zum ersten Mal seit dem Start neu gestartet werden.Jetzt bootet das Framework alle seine Dienste mit den entschlüsselten / Daten und das System ist einsatzbereit.
Starten eines verschlüsselten Geräts ohne Standardverschlüsselung
Dies geschieht, wenn Sie ein verschlüsseltes Gerät mit einem festgelegten Kennwort starten. Das Kennwort des Geräts kann eine PIN, ein Muster oder ein Kennwort sein.
Erkennen Sie, dass das Android-Gerät aufgrund des Flags verschlüsselt ist
ro.crypto.state = "encrypted"
vold
setztvold.decrypt
auftrigger_restart_min_framework
weil / data mit einem Passwort verschlüsselt ist.init
Legt fünf Eigenschaften fest, um die ursprünglichen Mount-Optionen für / data mit den übergebenen Parametern zu speicherninit.rc
.vold
verwendet diese Eigenschaften, um die Krypto-Zuordnung einzurichten:ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags
(8-stellige ASCII-Hexadezimalzahl mit vorangestelltem 0x)Das Framework startet und sieht, dass auf gesetzt
vold.decrypt
isttrigger_restart_min_framework
. Dies teilt dem Framework mit, dass es auf einertmpfs /data
Festplatte bootet und das Benutzerkennwort abrufen muss.Zunächst muss jedoch sichergestellt werden, dass der Datenträger ordnungsgemäß verschlüsselt wurde. Es sendet den Befehl
cryptfs cryptocomplete
anvold
.vold
Gibt 0 zurück, wenn die Verschlüsselung erfolgreich abgeschlossen wurde, -1 bei internem Fehler oder -2, wenn die Verschlüsselung nicht erfolgreich abgeschlossen wurde.vold
ermittelt dies, indem in den Krypto-Metadaten nach demCRYPTO_ENCRYPTION_IN_PROGRESS
Flag gesucht wird . Wenn dies eingestellt ist, wurde der Verschlüsselungsprozess unterbrochen und es sind keine verwendbaren Daten auf dem Gerät vorhanden.Wenn
vold
ein Fehler zurückgegeben wird, sollte die Benutzeroberfläche dem Benutzer eine Meldung anzeigen, in der er aufgefordert wird, das Gerät neu zu starten und auf die Werkseinstellungen zurückzusetzen, und dem Benutzer eine entsprechende Schaltfläche zuweisen.Nach
cryptfs cryptocomplete
erfolgreicher Ausführung zeigt das Framework eine Benutzeroberfläche an, in der Sie nach dem Festplattenkennwort gefragt werden. Die Benutzeroberfläche überprüft das Kennwort, indem der Befehlcryptfs checkpw
an gesendet wirdvold
. Wenn das Kennwort korrekt ist (was durch erfolgreiches Mounten des entschlüsselten/data
an einem temporären Speicherort und anschließendes Abmelden bestimmt wird), speichert vold den Namen des entschlüsselten Blockgeräts in der Eigenschaftro.crypto.fs_crypto_blkdev
und gibt den Status 0 an die Benutzeroberfläche zurück. Wenn das Kennwort falsch ist, wird -1 an die Benutzeroberfläche zurückgegeben.Die Benutzeroberfläche erstellt eine Krypto-Startgrafik und ruft dann vold mit dem Befehl auf
cryptfs restart
.vold
setzt die Eigenschaftvold.decrypt
auftrigger_reset_main
, die bewirkt , dassinit.rc
zu tunclass_reset main
. Dadurch werden alle Dienste in dermain
Klassetmpfs /data
gestoppt, sodass die Bereitstellung aufgehoben werden kann.vold
Anschließend wird die entschlüsselte reale/data
Partition angehängt und die neue Partition vorbereitet (die möglicherweise nie vorbereitet wurde, wenn sie mit der Löschoption verschlüsselt wurde, die in der ersten Version nicht unterstützt wird). Es setzt die Eigenschaftvold.post_fs_data_done
auf0
und setzt dannvold.decrypt
auftrigger_post_fs_data
. Dies führtinit.rc
dazu, dass es ausgeführt wirdpost-fs-data commands
. Sie erstellen alle erforderlichen Verzeichnisse oder Links und setzen sie dannvold.post_fs_data_done
auf1
. Sobaldvold
das1
in dieser Eigenschaft angezeigt wird, wird die Eigenschaftvold.decrypt
auf festgelegttrigger_restart_framework
. Dies führtinit.rc
dazu, dass Dienste in der Klassemain
erneut gestartet werden und auch Dienste in der Klasselate_start
zum ersten Mal seit dem Start neu gestartet werden .Jetzt bootet das Framework alle seine Dienste mit dem entschlüsselten / Datendateisystem und das System ist einsatzbereit.
Speichern des verschlüsselten Schlüssels
Der verschlüsselte Schlüssel wird in den Crypto-Metadaten gespeichert. Das Hardware-Backing wird mithilfe der Signaturfunktion von Trusted Execution Environment (TEE) implementiert. Zuvor haben wir den Hauptschlüssel mit einem Schlüssel verschlüsselt, der durch Anwenden
scrypt
des Benutzerpassworts und des gespeicherten Salt generiert wurde .Um den Schlüssel widerstandsfähig gegen Off-Box-Angriffe zu machen, erweitern wir diesen Algorithmus, indem wir den resultierenden Schlüssel mit einem gespeicherten TEE-Schlüssel signieren. Die resultierende Signatur wird dann durch eine weitere Anwendung von in einen Schlüssel geeigneter Länge umgewandelt
scrypt
. Dieser Schlüssel wird dann zum Ver- und Entschlüsseln des Hauptschlüssels verwendet. So speichern Sie diesen Schlüssel:scrypt
das Benutzerpasswort und das Salt an, um den 32-Byte-Zwischenschlüssel 1 (IK1) zu erstellen.scrypt
IK2 und Salt (dasselbe Salt wie in Schritt 2) auftragen, um ein 32-Byte-IK3 zu erhalten.quelle