Android圖案密碼,手勢鎖源碼解析

Android圖案密碼解鎖源碼解析

 

Android Lock Pattern 源碼解析 


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)
4.2.2 LockPatternView.java 

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 如果不爲空則停止添加,發送完成消息,全局刷新。
4.2.3 LockPatternUtils.java 

圖形摘要並加密 
  • 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 中點的順序生成編號序列,返回序列。
5. 安全性分析 

android-lockpattern 默認的加密存儲流程與 Android 系統的圖形解鎖是一致的,以 Android 系統爲例來破解圖形鎖。 


5.1 加密存儲過程 




5.2 破解思路 
  • 圖案總數固定:至少四個點、最多九個點、無重複點
  • 加密較弱:單次 SHA-1
  • 最快的方法:暴力猜解
5.3 實戰 

首先獲取系統圖形鎖加密摘要文件 
adb pull /data/system/gesture.key gesture.key 
參考4.2.3中的圖形摘要規則,然後我寫了一個 python 腳本,生成了 9 個點所有組合的摘要字符串,同時再生成對應的 SHA-1 HEX,這個字典也就 57m。 




把gesture.key中的加密字符串在字典中反查即可得出圖形鎖的原始信息摘要,然後就可以按步驟畫圖解鎖了。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章