Android圖案密碼解鎖源碼解析
1. 介紹
1.1 關於
Android 的圖案密碼解鎖,通過手勢連接 3 * 3 的點矩陣繪製圖案表示解鎖密碼。基於 Android Source Code。
1.2 特點
- 支持: Android 1.6+ (API 4+)。
- 無特殊依賴。
- 支持手機與平板的佈局。
- Stealth mode (invisible pattern)。
- 包含 5 種主題:Dark/Light
- Light with dark action bar (API 14+)
- Dark/Light dialogs
1.3 使用
1.3.1 Manifest 配置
複製代碼
1
2
3
|
<activity android:name="com.haibison.android.lockpattern.LockPatternActivity" android:theme="@style/Alp.42447968.Theme.Dark"
/> |
1.3.2 創建圖形鎖模式
複製代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private
static final int REQ_CREATE_PATTERN = 1; Intent
intent = new Intent(LockPatternActivity.ACTION_CREATE_PATTERN, null, your-context, LockPatternActivity.class); startActivityForResult(intent,
REQ_CREATE_PATTERN); @Override protected
void onActivityResult(int requestCode, int resultCode, Intent
data) { switch
(requestCode) { case
REQ_CREATE_PATTERN: { if
(resultCode == RESULT_OK) { char[]
pattern = data.getCharArrayExtra( LockPatternActivity.EXTRA_PATTERN); ... } break; } } } |
1.3.3 驗證圖形鎖
複製代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
private
static final int REQ_ENTER_PATTERN = 2; char[]
savedPattern = ... Intent
intent = new Intent(LockPatternActivity.ACTION_COMPARE_PATTERN, null, your-context,
LockPatternActivity.class); intent.putExtra(LockPatternActivity.EXTRA_PATTERN,
savedPattern); startActivityForResult(intent,
REQ_ENTER_PATTERN); @Override protected
void onActivityResult(int requestCode, int resultCode, Intent
data) { switch
(requestCode) { case
REQ_ENTER_PATTERN: { switch
(resultCode) { case
RESULT_OK: //
The user passed break; case
RESULT_CANCELED: //
The user cancelled the task break; case
LockPatternActivity.RESULT_FAILED: //
The user failed to enter the pattern break; case
LockPatternActivity.RESULT_FORGOT_PATTERN: //
The user forgot the pattern and invoked your recovery Activity. break; } int
retryCount = data.getIntExtra( LockPatternActivity.EXTRA_RETRY_COUNT,
0); break; } } } |
2. 總體設計
本項目較爲簡單,總體設計略過,具體實現請參考下面的分析。
3. 流程圖
3.1 創建解鎖圖案流程圖
3.2 驗證解鎖圖案流程圖
4. 詳細設計
4.1 類關係圖
4.2 核心類功能介紹
4.2.1 LockPatternActivity.java
LockPatternActivity類負責所有外部請求,根據ACTION_CREATE_PATTERN ACTION_COMPARE_PATTERN ACTION_VERIFY_CAPTCHA 等Action選擇操作模式,加載設置後初始化LockPatternView,在用戶完成操作後退出並返回結果。
主要方法說明:
- public void onCreate(Bundle savedInstanceState)
首次創建時調用,根據 intent 設置 theme,設置 resultIntent,調用 loadSettings() initContentView()。 - private void loadSettings()
根據 metaData 與 Settings 類的內容得到顯示模式、最少圖形點數、自動存儲、自定義加密等配置。 - private void initContentView()
根據 Aciton 與配置信息初始化 UI,實例化 OnPatternListener 設置到 LockPatternView 類的對象。 - private void doCheckAndCreatePattern(final List pattern)
首先檢查 pattern 是否合法,然後判斷 Intent 是否保存有特徵碼,如果沒有就把 pattern 加密並提取特徵碼 put 到 Intent,如果有就把特徵碼解密並與 pattern 對比,根據對比結果設置 UI。 - private void doComparePattern(final List pattern)
首先檢查 pattern 是否合法,然後從 Intent 或者 Settings 中 get 特徵碼,把特徵碼解密後與 pattern 對比,成功則調用 finishWithResultOk(null),失敗次數超過最大次數則調用 finishWithNegativeResult(result_failed)。 - private void finishWithResultOk(char[] pattern)
- private void finishWithNegativeResult(int resultCode)
LockPatternView類主要是顯示解鎖的圖形界面,在用戶操作的時候顯示連線與動畫,用戶操作完成後根據結果做提示。
添加圖形點
- private int getRowHit(float y)
遍歷所有圖形點行高,尋找座標 y 在哪個圖案點的行高範圍內。 - private int getColumnHit(float x)
遍歷所有圖形點列寬,尋找座標 x 在哪個圖案點的列寬範圍內。 - private Cell checkForNewHit(float x, float y)
根據getRowHit(float y)與getColumnHit(float x)返回的行、列判斷是否是新的圖形點,如果是返回新點,否則返回 null。 - private Cell detectAndAddHit(float x, float y)
調用checkForNewHit(float x, float y)返回當前圖形點,如圖形點非 null,繼續判斷 pattern list 是否爲空,如果不爲空就把 last 與當前的圖形點之間同一直線的其他點加入 list,然後把當前點加入 list。
- handleActionDown(MotionEvent event)
首先清理屏幕,獲取當前手指的座標,調用detectAndAddHit(float x, float y)並判斷其返回值發送通知與局部刷新。
- private void handleActionMove(MotionEvent event)
檢查手指移動過程中每一個點的座標,判斷如果 pattern list 不爲空,則把最後一個圖形點的座標與當前手指座標的區域進行局部刷新,如果在移動過程中加入了新的圖形點則以此點座標繼續局部刷新。
- private void handleActionUp(MotionEvent event)
檢查 pattern list 如果不爲空則停止添加,發送完成消息,全局刷新。
圖形摘要並加密
- public static String patternToSha1(List pattern)
調用List<LockPatternView.Cell> pattern把 pattern list 進行信息摘要,然後使用 SHA-1 算法加密,返回加密的摘要。 - public static String patternToString(List pattern)
把 pattern list 進行信息摘要,從左上角起編號爲 00,至右下角止編號爲 08,按照 list 中點的順序生成編號序列,返回序列。
android-lockpattern 默認的加密存儲流程與 Android 系統的圖形解鎖是一致的,以 Android 系統爲例來破解圖形鎖。
5.1 加密存儲過程
5.2 破解思路
- 圖案總數固定:至少四個點、最多九個點、無重複點
- 加密較弱:單次 SHA-1
- 最快的方法:暴力猜解
首先獲取系統圖形鎖加密摘要文件
adb pull /data/system/gesture.key gesture.key
參考4.2.3中的圖形摘要規則,然後我寫了一個 python 腳本,生成了 9 個點所有組合的摘要字符串,同時再生成對應的 SHA-1 HEX,這個字典也就 57m。
把gesture.key中的加密字符串在字典中反查即可得出圖形鎖的原始信息摘要,然後就可以按步驟畫圖解鎖了。