- 对本书的赞誉
- 前言
- 基础篇
- 第 1 章 Android 中锁屏密码加密算法分析
- 第 2 章 Android 中 NDK 开发
- 第 3 章 Android 中开发与逆向常用命令总结
- 第 4 章 so 文件格式解析
- 第 5 章 AndroidManifest.xml 文件格式解析
- 第 6 章 resource.arsc 文件格式解析
- 第 7 章 dex 文件格式解析
- 防护篇
- 第 8 章 Android 应用安全防护的基本策略
- 第 9 章 Android 中常用权限分析
- 第 10 章 Android 中的 run-as 命令
- 第 11 章 Android 中的 allowBackup 属性
- 第 12 章 Android 中的签名机制
- 第 13 章 Android 应用加固原理
- 第 14 章 Android 中的 so 加固原理
- 工具篇
- 第 15 章 Android 逆向分析基础
- 第 16 章 反编译神器 apktool 和 Jadx
- 第 17 章 Hook 神器 Xposed
- 第 18 章 脱壳神器 ZjDroid
- 第 19 章 Native 层 Hook 神器 Cydia Substrate
- 操作篇
- 第 20 章 静态方式逆向应用
- 第 21 章 动态调试 smali 源码
- 第 22 章 IDA 工具调试 so 源码
- 第 23 章 逆向加固应用
- 第 24 章 逆向应用经典案例分析
- 第 25 章 Android 中常见漏洞分析
- 第 26 章 文件加密病毒 Wannacry 样本分析
1.2 密码算法分析
在设置锁屏密码界面,用工具获取当前的 View 类,然后一步一步跟入,最终会跟到一个锁屏密码工具类:LockPatternUtils.java。每个版本可能实现逻辑不一样,这里用 5.1 版本的源码进行分析。
1.2.1 输入密码算法分析
找到源码之后,首先来分析一下输入密码算法:
可以看到有一个方法 passwordToHash,参数为用户输入的密码和当前用户对应的 id,一般设备不会有多个用户,所以这里的 userId 是默认值 0。下面就是最为核心的加密算法了:原文密码+设备的 salt 值,然后分别进行 MD5 和 SHA-1 操作,转化成 hex 值再次拼接,得到的就是最终保存到本地的加密密码内容。而这里最重要的是如何获取设备对应的 salt 值,这可以一步一步跟踪代码:
查看 getSalt 方法,首先根据字段 key 为 lockscreen.password_salt 从一个地方获取 salt 值,如果发现这个值为 0,就随机生成一个,然后将其保存到那个地方,最后将 salt 转化成 hex 值即可。现在需要找到这个地方,继续跟踪代码:
猜想应该是保存到一个数据库中了,继续跟踪代码:
通过在 ServiceManager 中获取一个服务来进行操作,在 Android 中,像这种获取服务的方式最终实现逻辑都是在 XXXService 类中,这里是 LockSettingsService.java 类,找到这个类,查看它的 getLong 方法:
其实到这里就可以看出,非常肯定是数据库中保存的,继续跟踪代码:
果然发现是保存到一个数据库中,继续查看 LockSettingsStorage.java 类:
看到了,数据库名字叫作 locksettings.db,那么它保存在哪里呢?继续看这个类:
可以看到有两个 key 文件,它们就是用来保存加密之后的手势密码和输入密码的,将信息保存到本地,下次开机解锁需要读取这个文件内容进行密码比对。看到一个目录是 system,所以数据库和这两个 key 文件很可能保存到目录/data/system/下了,为了再证实一下,直接用 find 命令去根目录下搜索这个数据库文件也是可以的。最终确定是该目录:
这里可能会提示找不到 find 命令,这时需要安装 busybox 工具,才能使用这个命令。找到这个数据库文件就好办了,直接取出来,然后用 SQLite 工具进行查看即可,当然也可以直接在手机中查看。为了方便还是取出来看,如图 1-1 所示。
图 1-1 数据库信息
这里看到了表格字段,并且获取到这个值了,那么下面就要用这个值来验证上面的分析是否正确。首先给设备设置一个简单的输入密码,这里直接输入简单的“1234”,然后会在/data/system 目录下生成一个密码加密 key 文件/data/system/password.key,将该文件导出来,如图 1-2 所示。
图 1-2 加密文件
下面就用简单的 Java 代码手动实现这个算法,看看分析是否正确。加密算法不用自己写,直接从上面的源码中拷贝出来就可以了。代码如下:
这里的 salt 值是我们从数据库中得到的,不过要记得进行 hex 转化:
然后用“1234”原文密码去生成加密之后的信息:
运行结果如图 1-3 所示。
图 1-3 运行结果
可以发现内容和上面的 password.key 内容完全一致,也就验证了上面的分析完全正确。到这里就分析完了输入密码的加密算法,总结一点就是:MD5(输入明文密码+设备的 salt).Hex+SHA1(输入明文密码+设备的 salt).Hex 就是最终的加密内容。而这里最重要的是如何获取设备的 salt 值,可以用反射机制进行获取,新建一个简单的 Android 项目:
这样就不用去查看数据库获取 salt 值了,方便快捷,打印的日志信息如下:
这是数据库中的 long 类型值转化成 hex 之后的值。
1.2.2 手势密码算法分析
下面来分析手势密码,代码依然在 LockPatternUtils.java 中:
这个算法比较简单,就是九宫格图案转化成字节数组,然后用 SHA1 加密即可。关于九宫格不再多说了,从 0 开始顺时针计数到 8,类似图 1-4 所示。
图 1-4 九宫格
看一下代码,有行和列之分。比如 L 形状的手势密码应该是 00 03 06 07 08,这样组成五个字节。这里为了验证手势密码是否正确,设置一个简单的手势密码,如图 1-5 所示。
图 1-5 简单的手势密码
然后在/data/system 目录下生成一个密码文件/data/system/gesture.key,取出来用二进制工具查看,不然可能看到的是乱码,这里用的是 010Editor 工具查看,如图 1-6 所示。
图 1-6 手势密码加密内容
为了最大化地还原算法,依然把源码拷贝出来,然后定义一个手势九宫格类,构造出这个手势的点数据:
这是源码的加密算法,下面再构造出手势点数据:
手势点数据应该是 00 01 02 05 08,打印看结果,如图 1-7 所示。
图 1-7 运行结果
从运行结果发现,一模一样,这样就完美地分析完了手势密码加密算法。
这里再总结一下两种方式锁屏密码算法。
第一种:输入密码算法
对输入的明文密码+设备的 salt 值进行 MD5 和 SHA1 操作,之后转化成 hex 值进行拼接即可,最终加密信息保存到本地目录/data/system/password.key。
第二种:手势密码算法
将九宫格手势密码中的点数据转化成对应的字节数组,然后直接进行 SHA1 加密即可。最终加密信息保存到本地目录/data/system/gesture.key。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论