Я цитую тут посібник з Android , але:
ПРИМІТКА:
Я використовував джерело, не має прямого відношення до Marshmallow, але стосується Lollipop і вище.
TL: DR
Я зараз вирішу питання ОП. Далі випливатимуть технічні деталі.
Ключ шифрування за замовчуванням надходить з апаратного джерела (мікросхема, аналогічна TPM) та пароля за замовчуванням AOSP, визначеного як default_password
у cryptfs.c
вихідному файлі, див. Нижче.
Так, не просто за замовчуванням, але будь-який пароль вводиться у ключ і зберігається на чіпі, подібному до TPM, який називається TEE (скорочення "Довірене середовище виконання", див. Нижче для подальшої інформації).
Хакер з доступом UART / JTAG до чіпів на SoC пристрою технічно може отримати доступ до ключа TEE, або ж користувацьке ядро може випустити цю інформацію в хакер. Деякі агентства з трьома листами в теоріях конспірації, можливо, можуть співпрацювати з OEM, щоб отримати ці незахищені ядра, які використовуються у виробничих пристроях, але я б не закладав у них багато магазинів. Знову див. Останній розділ цієї відповіді для отримання більш детальної інформації.
Єдине, що не дозволяє хакеру отримати доступ до ключа, - це чимало зусиль, необхідних для цього.
- Перевірка хешу (контрольної суми) мікропрограмного забезпечення (Google називається "Перевірена завантаження" ) насправді робиться на Lollipop і вище за замовчуванням (і доступна від JellyBean 4.3 далі), модулем ядра, який називається
dm-verity
. Однак це не залежить від стану шифрування.
Джерело: Тут посібник із безпеки AOSP .
- Про процес, пов’язаний із розшифруванням системи користувальницьким паролем, дивіться нижче. Я просто скажу тут, що пароль користувача бере участь як у створенні, так і у використанні ключа шифрування.
Огляд
Під час першого завантаження пристрій створює довільно генерований 128-розрядний головний ключ, а потім хеширує його паролем за замовчуванням і зберігається солі. Пароль за замовчуванням: "default_password" Однак отриманий хеш також підписується через TEE (наприклад, TrustZone), який використовує хеш підпису для шифрування головного ключа.
Ви можете знайти пароль за замовчуванням, визначений у файлі cryptfs.c проекту з відкритим кодом Android .
Коли користувач встановлює PIN-код / пропуск або пароль на пристрої, лише 128-бітний ключ повторно шифрується та зберігається. (тобто зміни PIN-коду / проходу / шаблону користувача НЕ викликають повторного шифрування розділу розділів даних користувача.)
Запуск зашифрованого пристрою з шифруванням за замовчуванням
Це відбувається, коли ви завантажуєте зашифрований пристрій без пароля. Оскільки пристрої Android 5.0 шифруються під час першого завантаження, не повинно бути встановленого пароля, а отже, це стан шифрування за замовчуванням.
- Виявити зашифровані / дані без пароля
Визначте, що пристрій Android зашифровано, оскільки / неможливо встановити дані та встановити один із прапорів encryptable
або forceencrypt
встановлено.
vold
встановлює vold.decrypt
в trigger_default_encryption
, який запускає defaultcrypto
службу. trigger_default_encryption
перевіряє тип шифрування, щоб побачити, чи / зашифровані дані з паролем або без нього.
- Розшифрування / дані
Створює dm-crypt
пристрій через блоковий пристрій, щоб пристрій був готовий до використання.
- Монтаж / дані
vold
потім монтує розшифрований розділ real / data та готує новий розділ. Він встановлює властивість vold.post_fs_data_done
до 0
і потім встановлює vold.decrypt
в trigger_post_fs_data
. Це змушує init.rc
запускати свої post-fs-data
команди. Вони будуть створювати необхідні каталоги і посилання , а потім встановити vold.post_fs_data_done
в 1
.
Після того, як vold
бачить 1 в цій власності, вона встановлює властивість vold.decrypt
в: trigger_restart_framework
. Це змушує init.rc
запускати послуги в класі main
знову, а також запускати служби в класі late_start вперше після завантаження.
- Початкові рамки
Тепер фреймворк завантажує всі свої служби, використовуючи розшифровані / дані, і система готова до використання.
Запуск зашифрованого пристрою без шифрування за замовчуванням
Це відбувається, коли ви завантажуєте зашифрований пристрій, на якому встановлений пароль. Пароль пристрою може бути шпилькою, малюнком або паролем.
- Виявити зашифрований пристрій за допомогою пароля
Визначте, що пристрій Android зашифровано через прапор ro.crypto.state = "encrypted"
vold
набори vold.decrypt
для trigger_restart_min_framework
тому , що / дані шифруються за допомогою пароля.
- Монтувати tmpfs
init
встановлює п'ять властивостей для збереження початкових параметрів кріплення, заданих для / даних, з параметрами, переданими з init.rc
. vold
використовує ці властивості для налаштування криптографічного відображення:
ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags
(8-значний шістнадцятковий номер ASCII, перед яким 0x)
- Запустіть рамки для запиту пароля
Рамка запускається і бачить, що vold.decrypt
встановлено trigger_restart_min_framework
. Це говорить про те, що він завантажується на tmpfs /data
диск і йому потрібно отримати пароль користувача.
По-перше, проте, потрібно переконатися, що диск був правильно зашифрований. Він надсилає команду cryptfs cryptocomplete
на vold
. vold
повертає 0, якщо шифрування було успішно завершено, -1 за внутрішньою помилкою, або -2, якщо шифрування не було успішно завершено. vold
визначає це, дивлячись у криптовалютні метадані CRYPTO_ENCRYPTION_IN_PROGRESS
прапора. Якщо його встановлено, процес шифрування був перерваний, і на пристрої немає корисних даних.
Якщо vold
повертається помилка, користувальницький інтерфейс повинен відображати повідомлення користувачеві про перезавантаження та заводське скидання пристрою та надати користувачеві кнопку натиснути для цього.
- Розшифруйте дані паролем
Після cryptfs cryptocomplete
успішної роботи в рамках відображається інтерфейс користувача з запитом пароля диска. UI перевіряє пароль, надсилаючи команду cryptfs checkpw
на vold
. Якщо пароль правильний (що визначається успішним встановленням розшифрованого /data
у тимчасовому місці, а потім його відключення), vold зберігає ім'я розшифрованого блокового пристрою у властивості ro.crypto.fs_crypto_blkdev
та повертає статус 0 до інтерфейсу користувача. Якщо пароль невірний, він повертає -1 в інтерфейс користувача.
- Зупинка рамки
Користувальницький інтерфейс виставляє графічну завантажувальну графіку, а потім викликає команду vold cryptfs restart
. vold
встановлює властивість vold.decrypt
до trigger_reset_main
, що змушує init.rc
робити class_reset main
. Це зупиняє всі сервіси в main
класі, що дозволяє tmpfs /data
відключити функцію .
- Монтаж / дані
vold
потім монтує розшифрований реальний /data
розділ і готує новий розділ (який, можливо, ніколи не був би підготовлений, якщо він був зашифрований за допомогою параметра wipe, який не підтримується у першому випуску). Він встановлює властивість vold.post_fs_data_done
до 0
і потім встановлює vold.decrypt
в trigger_post_fs_data
. Це змушує init.rc
запустити його post-fs-data commands
. Вони будуть створювати необхідні каталоги і посилання , а потім встановити vold.post_fs_data_done
в 1
. Після того, як vold
бачить 1
в цій власності, вона встановлює властивість vold.decrypt
в trigger_restart_framework
. Це змушує init.rc
запускати послуги в класі main
знову, а також запускати послуги в класі late_start
вперше після завантаження.
- Почніть повну рамку
Тепер фреймворк завантажує всі свої сервіси, використовуючи розшифровану файлову систему даних, і система готова до використання.
Зберігання зашифрованого ключа
Зашифрований ключ зберігається у крипто-метаданих. Резервне копіювання обладнання реалізується за допомогою можливості підпису TrE-середовища для підпису (TEE). Раніше ми зашифрували головний ключ, створений ключем, застосованим scrypt
до пароля користувача та збереженої солі.
Для того, щоб зробити ключ стійким до нестандартних атак, ми розширюємо цей алгоритм, підписуючи отриманий ключ із збереженим ключем TEE. Потім підпис перетворюється на відповідний ключ довжини ще одним додатком scrypt
. Потім цей ключ використовується для шифрування та розшифрування головного ключа. Щоб зберегти цей ключ:
- Створіть випадковий 16-байтовий ключ шифрування диска (DEK) та 16-байтну сіль.
- Застосуйте
scrypt
до пароля користувача та солі для отримання 32-байтового проміжного ключа 1 (IK1).
- Прокладка IK1 з нульовим байтом до розміру приватного ключа, зв’язаного з обладнанням (HBK). Зокрема, ми розміщуємо як: 00 || IK1 || 00..00; один нульовий байт, 32 байти IK1, 223 нульових байти.
- Підписаний IK1 із знаком HBK для отримання 256-байтного IK2.
- Нанесіть
scrypt
на IK2 та сіль (таку ж сіль, як на етапі 2), щоб отримати 32-байт IK3.
- Використовуйте перші 16 байт IK3 як KEK, а останні 16 байт як IV.
- Шифруйте DEK за допомогою AES_CBC, з ключем KEK та вектором ініціалізації IV.