Storage of previous lock screen passwords in Android M
Before Android M, the storage format of lock screen passwords was simple, using 64-bit random numbers as the salt value, which was stored in the SQLite database /data/system/. When the password is stored, the entered password will be added to this random number to form a new string. Then SHA-1 and MD5 are encrypted respectively on the new strings, and the encrypted ciphertext is spliced through MD5 + SHA-1 to form a new ciphertext stored in /data/system/, with a total of 72 bits. The encrypted form is as follows:
/data/system # cat password.keyB40C2F6FE4E89F3386D4E689B135304410D64951914FB35770FDAC58B694177B29297A80
The detailed information of the password is stored in /data/system/device_policies.xml, and the content is similar to the following:
/data/system # cat device_policies.xml
The two fields mainly used are the type of password. The values of simple passwords and complex passwords are different. length is the length of passwords. Other fields store the number of various characters in the password.
Storage of lock screen password in Android M
In Android M, the storage format of lock screen password has changed. The default storage format is described in /system/gatekeeper/include/gatekeeper/password_handle.h as follows:
typedef uint64_t secure_id_t;typedef uint64_t salt_t;/** * structure for easy serialization * and deserialization of password handles. */static const uint8_t HANDLE_VERSION = 2;struct __attribute__ ((__packed__)) password_handle_t { // fields included in signature uint8_t version; secure_id_t user_id; uint64_t flags; // fields not included in signature salt_t salt; uint8_t signature[32]; bool hardware_backed;};
The default version is 2, user_id is the Android user id, signature stores the ciphertext, hardware_backed stores the encryption method, 0 indicates that the ciphertext is software encryption, and 1 indicates that the ciphertext is encrypted through the TEE environment.
After the password is encrypted, it is stored in /data/system/ by default in password_handle_t format. Password generation and verification are implemented in the HAL layer through functions in system/core/gatekeeperd/. It is registered as gatekeeperd service when the system is started. When the service starts, it will call the GateKeeperProxy() object. This type of constructor will look for the TEE module. If it is found, it will be encrypted and decrypted through the TEE device. If it is not found, it will be encrypted and decrypted through a software device.
Here we mainly analyze the logic decryption through soft ar equipment. When decrypting, the following function in system/core/gatekeeperd/ is called:
int verify(uint32_t uid, const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, const uint8_t *provided_password, uint32_t provided_password_length, bool *request_reenroll)
In this function, since TEE is not used, it will be called to the software device verification system/core/gatekeeperd/:
int SoftGateKeeperDevice::verify(uint32_t uid, uint64_t challenge, const uint8_t *enrolled_password_handle, uint32_t enrolled_password_handle_length, const uint8_t *provided_password, uint32_t provided_password_length, uint8_t **auth_token, uint32_t *auth_token_length, bool *request_reenroll)
The function performs verification. This function processes the passed information and then hands it over to the system/gatekeeper/
void GateKeeper::Verify(const VerifyRequest &request, VerifyResponse *response)
Processing, here the parameters are processed and reorganized and then handed over to
bool GateKeeper::DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password)
Check, in this function, call it again
bool GateKeeper::CreatePasswordHandle(SizedBuffer *password_handle_buffer, salt_t salt, secure_id_t user_id, uint64_t flags, uint8_t handle_version, const uint8_t *password, uint32_t password_length)
Put the above mentioned /data/system/
The information stored in the file is parsed and then called
ComputePasswordSignature(password_handle->signature, sizeof(password_handle->signature), password_key, password_key_length, to_sign, sizeof(to_sign), salt);
The function encrypts the entered password. From here, we can see that to encrypt the entered password into ciphertext, only the salt value in the stored password is used. This function is in system/core/gatekeeperd/, which calls the crypto library
crypto_scrypt(password, password_length, reinterpret_cast(&salt), sizeof(salt), N, r, p, signature, signature_length);
Store the entered password in signature and return. This function will eventually be encrypted through SHA256, and the default values of N, r, and p in the parameters are:
static const uint64_t N = 16384;static const uint32_t r = 8;static const uint32_t p = 1;
After the above processing, the ciphertext obtained after encrypting the input password is compared with the ciphertext stored in the mobile phone and then returned to the verification result, thereby determining whether the input password is correct or not.
In Android M, the previous method of directly verifying passwords in the Java layer was changed, and the password verification was processed through the HAL layer services. At the same time, support for TEE was added, which greatly improved the security of lock screen passwords. At the same time, it can also conveniently support other security features, improving the security of the entire system.
The above article in-depth understanding of the Android M lock screen password storage method is all the content I share with you. I hope you can give you a reference and I hope you can support me more.