深入理解Android M 锁屏密码存储方式

Android M 之前锁屏密码的存储

在 Android M 之前,锁屏密码的存储格式很简单,其使用了 64 位随机数作为 salt 值,此 salt 值被存储在 SQLite 数据库 /data/system/locksettings.db 中。密码在存储的时候,会将输入的密码加上此随机数组成新的字符串。然后对新的字符串分别进行 SHA-1 和 MD5 加密,将加密后的密文通过 MD5 + SHA-1 的方式进行字符串拼接,组成新的密文存储在 /data/system/password.key 中,共有 72 位。其加密后的形式如下:

/data/system # cat password.keyB40C2F6FE4E89F3386D4E689B135304410D64951914FB35770FDAC58B694177B29297A80

而密码的详细信息,存储在 /data/system/device_policies.xml 中,内容类似如下:

/data/system # cat device_policies.xml

其中主要用到的两个字段 quality 是密码的类型,简单密码和复杂密码的值不同,length 是密码的长度,其他字段存储密码中各种字符的数量。

Android M 中锁屏密码的存储

在 Android M 中,锁屏密码的存储格式发生了变化,其默认的存储格式在/system/gatekeeper/include/gatekeeper/password_handle.h 中描述如下:

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;};

其中 version 默认是 2,user_id 是 Android 用户 id ,signature 存储的便是密文,hardware_backed 存储的是加密方式,0 表示密文是软件加密,而 1 表示密文是通过 TEE 环境进行加密得到的。

密码加密后默认以 password_handle_t 格式存储在/data/system/gatekeeper.password.key 中。密码的生成和校验,在 HAL 层是通过 system/core/gatekeeperd/gatekeeperd.cpp 中的函数实现的。其在系统启动时被注册为 gatekeeperd 服务,服务在启动的时候会调用 GateKeeperProxy()对象,此类的构造函数会去查找 TEE module,如果找到,则通过 TEE 设备进行加解密,如果没有找到,则通过一个软件设备进行加解密。

这里主要分析下通过软甲设备解密的逻辑。解密时,会调用到system/core/gatekeeperd/gatekeeperd.cpp 中的以下函数:

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)

在此函数中,由于没有使用 TEE,所以会调用到软件设备验证 system/core/gatekeeperd/SoftGateKeeperDevice.cpp 中的:

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)

函数进行校验,此函数对传进来的信息进行处理后交到system/gatekeeper/gatekeeper.cpp 中的

void GateKeeper::Verify(const VerifyRequest &request, VerifyResponse *response)

进行处理,在这里对参数进行一系列处理和重新组织后再交给

bool GateKeeper::DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password)

进行校验,在此函数中,再调用

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)

将上面提到的 /data/system/gatekeeper.password.key

文件中存储的信息进行解析,然后调用

ComputePasswordSignature(password_handle->signature, sizeof(password_handle->signature),
password_key, password_key_length, to_sign, sizeof(to_sign), salt);

函数将输入的密码进行加密,从这里可以看到,输入的密码要加密成密文只需要用到存储的密码中的 salt 值,此函数在system/core/gatekeeperd/SoftGateKeeper.h 中,其调用 crypto 库中的

crypto_scrypt(password, password_length, reinterpret_cast(&salt),
sizeof(salt), N, r, p, signature, signature_length);

将输入的密码存储在 signature 中并返回。此函数最终会通过 SHA256 进行加密,参数中的 N, r, p 默认为如下值:

static const uint64_t N = 16384;static const uint32_t r = 8;static const uint32_t p = 1;

通过以上处理后对输入的密码加密后得到的密文与手机中存储的密文进行比较后返回校验结果,从而判断输入的密码的正确与否。

在 Android M 中,改变了之前直接在 Java 层进行密码校验的方式,将密码的校验通过 HAL 层的服务进行处理,同时加入对 TEE 的支持,使得锁屏密码的安全性大大提升,同时也可以方便的支持其他的安全特性,提升了整个系统的安全性。

以上这篇深入理解Android M 锁屏密码存储方式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 轻松实现Android锁屏功能

    锁屏需要引入设备超级管理员.在文档Android开发文档的Administration中有详细的说明.Android设备管理系统功能和控制访问. 主要有一下几个步骤: 1  创建广播接收者,实现DeviceAdminReceiver package com.andy.lockscreen; import android.app.admin.DeviceAdminReceiver; /** * @author Zhang,Tianyou * @version 2014年11月20日 下午9:51:

  • 深入理解Android M 锁屏密码存储方式

    Android M 之前锁屏密码的存储 在 Android M 之前,锁屏密码的存储格式很简单,其使用了 64 位随机数作为 salt 值,此 salt 值被存储在 SQLite 数据库 /data/system/locksettings.db 中.密码在存储的时候,会将输入的密码加上此随机数组成新的字符串.然后对新的字符串分别进行 SHA-1 和 MD5 加密,将加密后的密文通过 MD5 + SHA-1 的方式进行字符串拼接,组成新的密文存储在 /data/system/password.ke

  • Android屏幕锁屏弹窗的正确姿势DEMO详解

    在上篇文章给大家介绍了Android程序开发仿新版QQ锁屏下弹窗功能.今天通过本文给大家分享android锁屏弹窗的正确姿势. 最近在做一个关于屏幕锁屏悬浮窗的功能,于是在网上搜索了很多安卓屏幕锁屏的相关资料,鉴于网上的资料比较零碎,所以我在这里进行整理总结.本文将从以下两点对屏幕锁屏进行解析: 1. 如何监听系统屏幕锁屏 2. 如何在锁屏界面弹出悬浮窗 如何监听系统屏幕锁屏 经过总结,监听系统的锁屏可以通过以下两种方式: 1) 代码直接判定 2) 接收广播 1) 代码直接判定 代码判断方式,也

  • android九宫格锁屏控件使用详解

    本文实例为大家分享了android九宫格锁屏控件的具体代码,供大家参考,具体内容如下 代码: public class LockView extends View {     //半径     private int radius;     //中心小圆半径     private int smallRadius;     //一行个数     private int column;     //选中颜色     private int selectColor;     //未选中颜色    

  • android禁止锁屏保持常亮(示例代码)

    在播放video的时候在mediaplayer mMediaPlayer.setScreenOnWhilePlaying(true); 已经设置了,在原生的android没有问题和在defy上也没有问题,一到三星的galaxy上就有问题,不知道三星他们改了哪些地方.一般的话设置了播放视频屏幕没有自动.但是在三星上就出了问题. 只好再找找.一般的话设置有两种方法. 如下: 复制代码 代码如下: 1. getWindow().addFlags(WindowManager.LayoutParams.F

  • Android实现锁屏荧光效果

    前言 这是几个月前写的博文,睡前看了觉得有些敷衍,还是改了再发吧. 之前的博客做了个锁屏应用,在以前各种酷炫的锁屏效果是很流行的,有时候会去锁屏市场看看哪些自己喜欢的特效,发现有个很酷炫的荧光解锁的效果,于是想着能否自己实现一下. 锁屏效果: 原理: 锁屏的原理在前些篇章已经有做介绍了,这里主要讲荧光这种效果的实现. 原理要点: 1)关于荧光点,每一个荧光店都是我们一个对象实体,因此我们将其单独构造为一个类,它具有自己的一些属性,比如荧光开始时间,荧光点的半径,荧光点的生命周期等. /** *

  • Android开发笔记之: 数据存储方式详解

    无论是神马平台,神马开发环境,神马软件程序,数据都是核心.对于开发平台来讲,如果对数据的存储有良好的支持,那么对应用程序的开发将会有很大的促进作用.总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.其中文件和数据库可能用的稍多一些,文件用起来较为方便,程序可以自己定义格式:数据库用起稍烦锁一些,但它有它的优点,比如在海量数据时性能优越,有查询功能,可以加密,可以加锁,可以跨应用,跨平台等等:网络,则用于比较重要的事情,比如科研,勘探,航空等实时采集到的数据需要马上通过网络

  • Android开发之数据的存储方式详解

    在Android中,数据的存储分为两种方式: 1.直接以文件的形式存储在目录中 2.以json格式存储在数据库中 将数据以文件的存储又分为两种方式: 1.生成.txt文件 2.生成xml文件 那么今天就来详细的说一下以文件的形式存储,由于没有讲到数据库,在之后的课程中会讲到json格式存储在数据库中. 一.生成.txt文件 文件的生成无非就是我们Java中学习的输入输出流中的一部分,有Java基础相信都是很容易理解的,因为它真的很简单啦~~ 1.生成目录可以分为两种: 1)本机 2)SD卡 2.

  • Libgdx解决部分Android机型锁屏崩溃的方法

    libgdx使用了全屏模式之后,在某些机型会出现崩溃的情况,两年前就存在了,一直到现在为止,官方都没进行修复,其崩溃原因就是在源码AndroidGraphics.java中的onPause可以看到这样子的一段代码: void pause () { synchronized (synch) { if (!running) return; running = false; pause = true; while (pause) { try { // TODO: fix deadlock race c

  • Android如何实现锁屏状态下弹窗

    前言 想在锁屏上面实现弹窗,第一个想法就是利用 WindowManager 设置 Window 的 Flag,通过设置 Flag 的显示优先级来让窗口显示在锁屏的上面. 接下来就是试验可能相关的 Window Type 属性,验证该方案是否可行. 在尝试各个 Window Type 属性之前需要明确各个 Type 所需要的权限,下面是 com.android.internal.policy.impl.PhoneWindowManager.checkAddPermission 的源码: publi

  • Android程序开发仿新版QQ锁屏下弹窗功能

    新版的qq,可以在锁屏下弹窗显示qq消息,正好目前在做的项目也需要这一功能.经过各种试验和资料查找,终于实现,过程不难,但是却有一些地方需要注意. 下面是实现过程. 1.使用Activity,而不是View QQ的弹窗一开始我以为是悬浮View,用WindowManager去添加,但是无论如何就是不显示,后来在朋友提示下换成Activity来实现,在锁屏状态下就能弹窗了. 2.Activity的设置 Activity需要进行以下设置,才可以在锁屏状态下弹窗. 首先是onCreate方法,需要添加

随机推荐