1. 程式人生 > >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中的加密字串在字典中反查即可得出圖形鎖的原始資訊摘要,然後就可以按步驟畫圖解鎖了。