@@ -5,10 +5,13 @@ android-lockpattern 源码解析
5
5
> 分析者:[ 爱早起] ( https://github.com/liang7 ) ,校对者:[ Trinea] ( https://github.com/Trinea ) ,校对状态:未完成
6
6
7
7
###1 . 介绍
8
+
8
9
####1 .1 关于
10
+
9
11
Android 的图案密码解锁,通过手势连接 3 * 3 的点矩阵绘制图案表示解锁密码。基于 [ Android Source Code] ( https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/widget/LockPatternView.java ) 。
10
12
11
13
####1 .2 特点
14
+
12
15
- 支持: Android 1.6+ (API 4+)。
13
16
- 无特殊依赖。
14
17
- 支持手机与平板的布局。
@@ -19,74 +22,18 @@ Android 的图案密码解锁,通过手势连接 3 * 3 的点矩阵绘制图
19
22
- Dark/Light dialogs
20
23
- 有验证码模式。
21
24
22
- ###2 . 总体设计
23
- 本项目较为简单,总体设计略过,具体实现请参考下面的分析。
24
-
25
- ###3 . 流程图
26
- ####3 .1 创建解锁图案流程图
27
- ![ Create Pattern] ( image/CreatePattern.png )
25
+ ####1 .3 使用
28
26
29
- ####3 .2 验证解锁图案流程图
30
- ![ Compare Pattern] ( image/ComparePattern.png )
31
-
32
- ###4 . 详细设计
33
- ####4 .1 类关系图
34
- ![ Class Diagraph] ( image/Main.png )
35
-
36
- ####4 .2 核心类功能介绍
37
- #####4 .2.1 LockPatternActivity.java
38
- ` LockPatternActivity ` 类负责所有外部请求,根据` ACTION_CREATE_PATTERN ` ` ACTION_COMPARE_PATTERN ` ` ACTION_VERIFY_CAPTCHA ` 等` Action ` 选择操作模式,加载设置后初始化` LockPatternView ` ,在用户完成操作后退出并返回结果。
27
+ #####1 .3.1 Manifest 配置
39
28
40
- ** 主要方法说明:**
41
- * public void onCreate(Bundle savedInstanceState)
42
- 首次创建时调用,根据 intent 设置 theme,设置 resultIntent,调用 loadSettings() initContentView()。
43
- * private void loadSettings()
44
- 根据 metaData 与 Settings 类的内容得到显示模式、最少图形点数、自动存储、自定义加密等配置。
45
- * private void initContentView()
46
- 根据 Aciton 与配置信息初始化 UI,实例化 OnPatternListener 设置到 LockPatternView 类的对象。
47
- * private void doCheckAndCreatePattern(final List<Cell > pattern)
48
- 首先检查 pattern 是否合法,然后判断 Intent 是否保存有特征码,如果没有就把 pattern 加密并提取特征码 put 到 Intent,如果有就把特征码解密并与 pattern 对比,根据对比结果设置 UI。
49
- * private void doComparePattern(final List<Cell > pattern)
50
- 首先检查 pattern 是否合法,然后从 Intent 或者 Settings 中 get 特征码,把特征码解密后与 pattern 对比,成功则调用 finishWithResultOk(null),失败次数超过最大次数则调用 finishWithNegativeResult(result_failed)。
51
- * private void finishWithResultOk(char[ ] pattern)
52
- * private void finishWithNegativeResult(int resultCode)
53
-
54
- #####4 .2.2 LockPatternView.java
55
- ` LockPatternView ` 类主要是显示解锁的图形界面,在用户操作的时候显示连线与动画,用户操作完成后根据结果做提示。
56
-
57
- ** 添加图形点**
58
- * private int getRowHit(float y)
59
- 遍历所有图形点行高,寻找坐标 y 在哪个图案点的行高范围内。
60
- * private int getColumnHit(float x)
61
- 遍历所有图形点列宽,寻找坐标 x 在哪个图案点的列宽范围内。
62
- * private Cell checkForNewHit(float x, float y)
63
- 根据` getRowHit(float y) ` 与` getColumnHit(float x) ` 返回的行、列判断是否是新的图形点,如果是返回新点,否则返回 null。
64
- * private Cell detectAndAddHit(float x, float y)
65
- 调用` checkForNewHit(float x, float y) ` 返回当前图形点,如图形点非 null,继续判断 pattern list 是否为空,如果不为空就把 last 与当前的图形点之间同一直线的其他点加入 list,然后把当前点加入 list。
66
-
67
- ** 按下事件**
68
- * handleActionDown(MotionEvent event)
69
- 首先清理屏幕,获取当前手指的坐标,调用` detectAndAddHit(float x, float y) ` 并判断其返回值发送通知与局部刷新。
70
-
71
- ** 移动事件**
72
- * private void handleActionMove(MotionEvent event)
73
- 检查手指移动过程中每一个点的坐标,判断如果 pattern list 不为空,则把最后一个图形点的坐标与当前手指坐标的区域进行局部刷新,如果在移动过程中加入了新的图形点则以此点坐标继续局部刷新。
74
-
75
- ** 弹起事件**
76
- * private void handleActionUp(MotionEvent event)
77
- 检查 pattern list 如果不为空则停止添加,发送完成消息,全局刷新。
78
-
79
- ** onDraw**
80
-
81
- ###5 . 使用
82
- ####5 .1 准备
83
29
```
84
30
<activity
85
31
android:name="com.haibison.android.lockpattern.LockPatternActivity"
86
32
android:theme="@style/Alp.42447968.Theme.Dark" />
87
33
```
88
34
89
- ####5 .2 创建图形锁模式
35
+ #####1 .3.2 创建图形锁模式
36
+
90
37
```
91
38
private static final int REQ_CREATE_PATTERN = 1;
92
39
@@ -111,7 +58,7 @@ protected void onActivityResult(int requestCode, int resultCode,
111
58
}
112
59
```
113
60
114
- ####5 .3 验证图形锁
61
+ ##### 1 .3 .3 验证图形锁
115
62
116
63
```
117
64
private static final int REQ_ENTER_PATTERN = 2;
@@ -154,3 +101,109 @@ protected void onActivityResult(int requestCode, int resultCode,
154
101
}
155
102
}
156
103
```
104
+
105
+ ###2 . 总体设计
106
+
107
+ 本项目较为简单,总体设计略过,具体实现请参考下面的分析。
108
+
109
+ ###3 . 流程图
110
+
111
+ ####3 .1 创建解锁图案流程图
112
+
113
+ ![ Create Pattern] ( image/CreatePattern.png )
114
+
115
+ ####3 .2 验证解锁图案流程图
116
+
117
+ ![ Compare Pattern] ( image/ComparePattern.png )
118
+
119
+ ###4 . 详细设计
120
+
121
+ ####4 .1 类关系图
122
+
123
+ ![ Class Diagraph] ( image/Main.png )
124
+
125
+ ####4 .2 核心类功能介绍
126
+
127
+ #####4 .2.1 LockPatternActivity.java
128
+
129
+ ` LockPatternActivity ` 类负责所有外部请求,根据` ACTION_CREATE_PATTERN ` ` ACTION_COMPARE_PATTERN ` ` ACTION_VERIFY_CAPTCHA ` 等` Action ` 选择操作模式,加载设置后初始化` LockPatternView ` ,在用户完成操作后退出并返回结果。
130
+
131
+ ** 主要方法说明:**
132
+
133
+ * public void onCreate(Bundle savedInstanceState)
134
+ 首次创建时调用,根据 intent 设置 theme,设置 resultIntent,调用 loadSettings() initContentView()。
135
+ * private void loadSettings()
136
+ 根据 metaData 与 Settings 类的内容得到显示模式、最少图形点数、自动存储、自定义加密等配置。
137
+ * private void initContentView()
138
+ 根据 Aciton 与配置信息初始化 UI,实例化 OnPatternListener 设置到 LockPatternView 类的对象。
139
+ * private void doCheckAndCreatePattern(final List<Cell > pattern)
140
+ 首先检查 pattern 是否合法,然后判断 Intent 是否保存有特征码,如果没有就把 pattern 加密并提取特征码 put 到 Intent,如果有就把特征码解密并与 pattern 对比,根据对比结果设置 UI。
141
+ * private void doComparePattern(final List<Cell > pattern)
142
+ 首先检查 pattern 是否合法,然后从 Intent 或者 Settings 中 get 特征码,把特征码解密后与 pattern 对比,成功则调用 finishWithResultOk(null),失败次数超过最大次数则调用 finishWithNegativeResult(result_failed)。
143
+ * private void finishWithResultOk(char[ ] pattern)
144
+ * private void finishWithNegativeResult(int resultCode)
145
+
146
+ #####4 .2.2 LockPatternView.java
147
+
148
+ ` LockPatternView ` 类主要是显示解锁的图形界面,在用户操作的时候显示连线与动画,用户操作完成后根据结果做提示。
149
+
150
+ ** 添加图形点**
151
+
152
+ * private int getRowHit(float y)
153
+ 遍历所有图形点行高,寻找坐标 y 在哪个图案点的行高范围内。
154
+ * private int getColumnHit(float x)
155
+ 遍历所有图形点列宽,寻找坐标 x 在哪个图案点的列宽范围内。
156
+ * private Cell checkForNewHit(float x, float y)
157
+ 根据` getRowHit(float y) ` 与` getColumnHit(float x) ` 返回的行、列判断是否是新的图形点,如果是返回新点,否则返回 null。
158
+ * private Cell detectAndAddHit(float x, float y)
159
+ 调用` checkForNewHit(float x, float y) ` 返回当前图形点,如图形点非 null,继续判断 pattern list 是否为空,如果不为空就把 last 与当前的图形点之间同一直线的其他点加入 list,然后把当前点加入 list。
160
+
161
+ ** 按下事件**
162
+
163
+ * handleActionDown(MotionEvent event)
164
+ 首先清理屏幕,获取当前手指的坐标,调用` detectAndAddHit(float x, float y) ` 并判断其返回值发送通知与局部刷新。
165
+
166
+ ** 移动事件**
167
+
168
+ * private void handleActionMove(MotionEvent event)
169
+ 检查手指移动过程中每一个点的坐标,判断如果 pattern list 不为空,则把最后一个图形点的坐标与当前手指坐标的区域进行局部刷新,如果在移动过程中加入了新的图形点则以此点坐标继续局部刷新。
170
+
171
+ ** 弹起事件**
172
+
173
+ * private void handleActionUp(MotionEvent event)
174
+ 检查 pattern list 如果不为空则停止添加,发送完成消息,全局刷新。
175
+
176
+ #####4 .2.3 LockPatternUtils.java
177
+
178
+ ** 图形摘要并加密**
179
+
180
+ * public static String patternToSha1(List<LockPatternView.Cell> pattern)
181
+ 调用` List<LockPatternView.Cell> pattern ` 把pattern list进行信息摘要,然后使用SHA-1算法加密,返回加密的摘要。
182
+ * public static String patternToString(List<LockPatternView.Cell> pattern)
183
+ 把pattern list进行信息摘要,从左上角起编号为00,至右下角止编号为08,按照list中点的顺序生成编号序列,返回序列。
184
+
185
+ ####5 . 安全性分析
186
+
187
+ android-lockpattern默认的加密存储流程与Android系统的图形解锁是一致的,以Android系统为例来破解图形锁。
188
+
189
+ #####5 .1 加密存储过程
190
+
191
+ ![ Compare Pattern] ( image/sec.png )
192
+
193
+ #####5 .2 破解思路
194
+
195
+ * 图案总数固定:至少四个点、最多九个点、无重复点
196
+ * 加密较弱:单次SHA-1
197
+ * 最快的方法:暴力猜解
198
+
199
+ #####5 .3 实战
200
+
201
+ 首先获取系统图形锁加密摘要文件
202
+
203
+ `
204
+ adb pull /data/system/gesture.key gesture.key
205
+ `
206
+
207
+ 参考` 4.2.3 ` 中的图形摘要规则,然后我写了一个python脚本,生成了9个点所有组合的摘要字符串,同时再生成对应的SHA-1 HEX,这个字典也就57m。
208
+
209
+ 把` gesture.key ` 中的加密字符串在字典中反查即可得出图形锁的原始信息摘要,然后就可以按步骤画图解锁了。
0 commit comments