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 der cryptfs.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.
- Das Überprüfen des Hashs (der Prüfsumme) der Firmware ( von Google als "Verified Boot" bezeichnet ) erfolgt standardmäßig über Lollipop (und ist ab JellyBean 4.3 verfügbar) durch ein Kernelmodul mit dem Namen
dm-verity
. Dies ist jedoch unabhängig vom Verschlüsselungsstatus.
Quelle: AOSP-Sicherheitsleitfaden hier .
- Informationen zum Entschlüsseln des Systems mit einem benutzerdefinierten Kennwort finden Sie weiter unten. Ich sage Ihnen hier nur, dass das Benutzerpasswort sowohl bei der Erstellung als auch bei der Verwendung des Verschlüsselungsschlüssels eine Rolle spielt.
Ü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 verschlüsselte / Daten ohne Passwort
Erkennen Sie, dass das Android-Gerät verschlüsselt ist, weil / data nicht bereitgestellt werden kann und eines der Flags encryptable
oder forceencrypt
gesetzt ist.
vold
setzt vold.decrypt
auf trigger_default_encryption
, was den defaultcrypto
Dienst startet . trigger_default_encryption
Überprüft den Verschlüsselungstyp, um festzustellen, ob / data mit oder ohne Kennwort verschlüsselt ist.
- Entschlüsseln / Daten
Erstellt das dm-crypt
Gerät über dem Blockgerät, sodass das Gerät einsatzbereit ist.
- Mount / Daten
vold
Mounten Sie dann die entschlüsselte Real- / Datenpartition und bereiten Sie die neue Partition vor. Es setzt die Eigenschaft vold.post_fs_data_done
auf 0
und setzt dann vold.decrypt
auf trigger_post_fs_data
. Dies bewirkt , dass init.rc
seine laufen post-fs-data
Befehle. Sie erstellen alle erforderlichen Verzeichnisse oder Links und setzen sie dann vold.post_fs_data_done
auf 1
.
Sobald vold
die 1 in dieser Eigenschaft sieht, setzt es die Eigenschaft vold.decrypt
auf: trigger_restart_framework
. Dies führt init.rc
dazu, dass Dienste in der Klasse main
erneut gestartet werden und Dienste in der Klasse late_start zum ersten Mal seit dem Start neu gestartet werden.
- Starten Sie das Framework
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 verschlüsseltes Gerät mit einem Passwort
Erkennen Sie, dass das Android-Gerät aufgrund des Flags verschlüsselt ist ro.crypto.state = "encrypted"
vold
setzt vold.decrypt
auf trigger_restart_min_framework
weil / data mit einem Passwort verschlüsselt ist.
- Mounten Sie tmpfs
init
Legt fünf Eigenschaften fest, um die ursprünglichen Mount-Optionen für / data mit den übergebenen Parametern zu speichern init.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)
- Starten Sie das Framework, um zur Eingabe eines Kennworts aufzufordern
Das Framework startet und sieht, dass auf gesetzt vold.decrypt
ist trigger_restart_min_framework
. Dies teilt dem Framework mit, dass es auf einer tmpfs /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
an vold
. 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 dem CRYPTO_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.
- Daten mit Passwort entschlüsseln
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 Befehl cryptfs checkpw
an gesendet wird vold
. 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 Eigenschaft ro.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.
- Stoppen Sie das Framework
Die Benutzeroberfläche erstellt eine Krypto-Startgrafik und ruft dann vold mit dem Befehl auf cryptfs restart
. vold
setzt die Eigenschaft vold.decrypt
auf trigger_reset_main
, die bewirkt , dass init.rc
zu tun class_reset main
. Dadurch werden alle Dienste in der main
Klasse tmpfs /data
gestoppt, sodass die Bereitstellung aufgehoben werden kann.
- Mount / Daten
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 Eigenschaft vold.post_fs_data_done
auf 0
und setzt dann vold.decrypt
auf trigger_post_fs_data
. Dies führt init.rc
dazu, dass es ausgeführt wird post-fs-data commands
. Sie erstellen alle erforderlichen Verzeichnisse oder Links und setzen sie dann vold.post_fs_data_done
auf 1
. Sobald vold
das 1
in dieser Eigenschaft angezeigt wird, wird die Eigenschaft vold.decrypt
auf festgelegt trigger_restart_framework
. Dies führt init.rc
dazu, dass Dienste in der Klasse main
erneut gestartet werden und auch Dienste in der Klasse late_start
zum ersten Mal seit dem Start neu gestartet werden .
- Starten Sie das vollständige Framework
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:
- Generieren Sie einen zufälligen 16-Byte-Festplattenverschlüsselungsschlüssel (DEK) und 16-Byte-Salt.
- Wenden Sie
scrypt
das Benutzerpasswort und das Salt an, um den 32-Byte-Zwischenschlüssel 1 (IK1) zu erstellen.
- Füllen Sie IK1 mit 0 Byte der Größe des hardwaregebundenen privaten Schlüssels (HBK) auf. Insbesondere füllen wir auf als: 00 || IK1 || 00..00; Ein Null-Byte, 32 IK1-Bytes, 223 Null-Bytes.
- Mit HBK aufgefüllte IK1 signieren, um 256-Byte-IK2 zu erzeugen.
- Auf
scrypt
IK2 und Salt (dasselbe Salt wie in Schritt 2) auftragen, um ein 32-Byte-IK3 zu erhalten.
- Verwenden Sie die ersten 16 Bytes von IK3 als KEK und die letzten 16 Bytes als IV.
- DEK mit AES_CBC, mit Schlüssel KEK und Initialisierungsvektor IV verschlüsseln.