Android 指紋認證

来源:http://www.cnblogs.com/wuyudong/archive/2016/12/15/6184316.html
-Advertisement-
Play Games

安卓指紋認證使用智能手機觸摸感測器對用戶進行身份驗證。Android Marshmallow(棉花糖)提供了一套API,使用戶很容易使用觸摸感測器。在Android Marshmallow之前訪問觸摸感測器的方法不是標準的。 本文地址:http://wuyudong.com/2016/12/15/3 ...


安卓指紋認證使用智能手機觸摸感測器對用戶進行身份驗證。Android Marshmallow(棉花糖)提供了一套API,使用戶很容易使用觸摸感測器。在Android Marshmallow之前訪問觸摸感測器的方法不是標準的。

本文地址:http://wuyudong.com/2016/12/15/3146.html,轉載請註明出處。

使用安卓指紋認證有幾個好處:

1、更快更容易使用

2、安全:指紋可以識別你的身份唯一

3、線上交易更加的容易

在使用android指紋識別之前你必須遵循一些步驟,可能看起來真的很複雜,但本文將教你你一步一步實現。

結果就像下圖顯示的那樣:

開始 Android 指紋認證

就如上面所說,指紋認證過程有以下幾個步驟:

  • 驗證鎖屏是否是安全的,或者換句話說,它是用密碼或模式保護的
  • 確認在智能手機上已經有一個指紋是註冊的
  • 訪問 Android keystore 存儲將對象加密/解密的密鑰
  • 生成一個加密密鑰和密碼
  • 啟動認證過程
  • 實現一個回調類來處理身份認證事件

就是這些了,下麵來實現上面的步驟!

在開始的時候,先得開啟觸摸感測器與身份認證的許可權,在清單文件 Manifest.xml 中添加:

<uses-permission android:name="android.permission.USE_FINGERPRINT" />

現在是時候創建main activity 類來處理所有的認證步驟了.

驗證Android安全鎖屏

第一步是確認鎖屏是否是安全的,這個可以使用 KeyguardManager 和FingerprintManager 來解決。 我們可以通過使用 getSystemService 類獲取它們的實例:

// Keyguard Manager
KeyguardManager keyguardManager = (KeyguardManager)
                  getSystemService(KEYGUARD_SERVICE);

// Fingerprint Manager
fingerprintManager = (FingerprintManager) 
                 getSystemService(FINGERPRINT_SERVICE);

現在,我們的認證應用可以檢查是否所有的安全判斷都滿足:

private boolean checkFinger() {

  // Keyguard Manager
  KeyguardManager keyguardManager = (KeyguardManager)
           getSystemService(KEYGUARD_SERVICE);

  // Fingerprint Manager
  fingerprintManager = (FingerprintManager) 
         getSystemService(FINGERPRINT_SERVICE);

  try {
   // Check if the fingerprint sensor is present
   if (!fingerprintManager.isHardwareDetected()) {
     // Update the UI with a message
     message.setText("Fingerprint authentication not supported");
     return false;
   }

   if (!fingerprintManager.hasEnrolledFingerprints()) {
     message.setText("No fingerprint configured.");
     return false;
   }

   if (!keyguardManager.isKeyguardSecure()) {
     message.setText("Secure lock screen not enabled");
     return false;
   }
 }
 catch(SecurityException se) {
   se.printStackTrace();
 }
 return true;
}

註意到應用程式驗證了至少有一個指紋已經註冊否則認證過程將不會開始,下麵的圖片展示瞭如果沒有發現註冊指紋提示一個錯誤信息

如果一切就緒,一切判斷情況都滿足,認證應用產生密鑰並訪問Android store.

訪問Android keystore並生成密鑰

接下來的步驟就是訪問Android keystore 並產生密鑰來加密數據,應用程式在一個叫 generateKey() 的方法中單獨完成.

// Get the reference to the key store
keyStore = KeyStore.getInstance("AndroidKeyStore");

接著必須獲得密鑰生成器的引用:

// Key generator to generate the key
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, 
                 "AndroidKeyStore");

最後,我們必須初始化密鑰生成器:

keyGenerator.init( new
  KeyGenParameterSpec.Builder(KEY_NAME,
  KeyProperties.PURPOSE_ENCRYPT |
  KeyProperties.PURPOSE_DECRYPT)
  .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
  .setUserAuthenticationRequired(true)
  .setEncryptionPaddings(
    KeyProperties.ENCRYPTION_PADDING_PKCS7)
  .build());

 keyGenerator.generateKey();

註意到我們特別指出密鑰的使用: 加密和解密並且認證需要使用密鑰,最後應用程式生成了密鑰 (最後一行).

上面的代碼完整的方法如下:

private void generateKey() throws FingerprintException {
  try {
    // Get the reference to the key store
    keyStore = KeyStore.getInstance("AndroidKeyStore");

    // Key generator to generate the key
    keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,

      "AndroidKeyStore");

     keyStore.load(null);
     keyGenerator.init( new
       KeyGenParameterSpec.Builder(KEY_NAME,
      KeyProperties.PURPOSE_ENCRYPT |
      KeyProperties.PURPOSE_DECRYPT)
     .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
     .setUserAuthenticationRequired(true)
     .setEncryptionPaddings(
        KeyProperties.ENCRYPTION_PADDING_PKCS7)
    .build());

    keyGenerator.generateKey();
  }
  catch(KeyStoreException
   | NoSuchAlgorithmException
   | NoSuchProviderException
   | InvalidAlgorithmParameterException
   | CertificateException
   | IOException exc) {
    exc.printStackTrace();
    throw new FingerprintException(exc);
 }
}

創建Android Cipher

一旦密鑰準備好了,最後步驟就是使用之前生成的密鑰來創建Android Cipher ,代碼很簡單:

private Cipher generateCipher() throws FingerprintException {
  try {
    Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
     + KeyProperties.BLOCK_MODE_CBC + "/"
     + KeyProperties.ENCRYPTION_PADDING_PKCS7);
     SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
             null);
     cipher.init(Cipher.ENCRYPT_MODE, key);
     return cipher;
  }
  catch (NoSuchAlgorithmException
     | NoSuchPaddingException
     | InvalidKeyException
     | UnrecoverableKeyException
     | KeyStoreException exc) {
      exc.printStackTrace();
      throw new FingerprintException(exc);
  }
}

構建 Android 指紋認證 app

是時候將前面的方法組合起來創建我們的 Android 指紋識別app,這個app很簡單隻有一個 MainClass 調用上面所示的方法開始認證處理.

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  message = (TextView) findViewById(R.id.fingerStatus);
  Button btn = (Button) findViewById(R.id.authBtn);

  final FingerprintHandler fph = new FingerprintHandler(message);

  if (!checkFinger()) {
    btn.setEnabled(false);
  }
  else {
    // We are ready to set up the cipher and the key
   try {
     generateKey();
     Cipher cipher = generateCipher();
     cryptoObject =
      new FingerprintManager.CryptoObject(cipher);
  }
  catch(FingerprintException fpe) {
   // Handle exception
   btn.setEnabled(false);
  }
 }

 btn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
    message.setText("Swipe your finger");
    fph.doAuth(fingerprintManager, cryptoObject);
   }
  });
}

有幾點需要註意的,首先,Android app 創建一個 CryptoObject 對象來處理認證過程,接著,app 一個button,當用戶點擊它的時候認證過程開始,當上面的初始化判斷條件不滿足的時候這個 button 被隱藏。需要註意的最重要的事情是新類調用FingerprintHandler. 這個類是個接收認證處理事件的回調類,此外, 此類啟動認證過程的doauth方法.

Android 指紋認證回調

最後一步是創建一個回調類,這樣我們可以接收事件消息並能夠知道什麼時候認證成功或者除了一些問題,這個類繼承自 FingerprintManager.AuthenticationCallback.

public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
  private TextView tv;

  public FingerprintHandler(TextView tv) {
    this.tv = tv;
  }

  @Override
  public void onAuthenticationError(int errorCode, CharSequence errString) {
    super.onAuthenticationError(errorCode, errString);
    tv.setText("Auth error");
  }

  @Override
  public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
    super.onAuthenticationHelp(helpCode, helpString);
  }

  @Override
  public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
    super.onAuthenticationSucceeded(result);
    tv.setText("auth ok");
    tv.setTextColor(tv.getContext().getResources().
                getColor(android.R.color.holo_green_light));
  }

  @Override
  public void onAuthenticationFailed() {
    super.onAuthenticationFailed();
  }

  public void doAuth(FingerprintManager manager, 
                     FingerprintManager.CryptoObject obj) {
   CancellationSignal signal = new CancellationSignal();

   try {
    manager.authenticate(obj, signal, 0, this, null);
   }
   catch(SecurityException sce) {}
 }
}

有一些重要的方法需要註意,首先,doAuth 開啟認證處理,這個方法包含 CryptoObject 對象,一個取消信號和回調監聽器。下麵的圖片顯示了app 的響應動作:

這種情況下,用戶使用android指紋認證完成了認證。

如何在模擬器上面測試這個app?

要測試這個app,如果有可能使用具有感測器的真機來進行,然而你還可以在模擬器上進行測試app,在使用app之前,你必須配置igure the fingerprint accessing to the Security menu. 當系統要求你的指紋的時候你必須使用adb 命令模擬指紋接觸:

adb -e emu finger touch id(like 1,2, ecc.)

最後,當你的指紋搞定,你將得到下麵的提示:

最後希望你掌握了android 的指紋識別 api 並知道怎樣開發一款指紋識別 app 例子,enjoy :)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 用 :empty 區分空元素 相容性:不支持 IE8 Demo 假如我們有以上列表: <div class="item">a</div> <div class="item">b</div> <div class="item"></div> 我們希望可以對空元素和非空元素區別處理,那麼有兩種方案。 用 ...
  • window.screen.availWidth 返回當前屏幕寬度(空白空間) window.screen.availHeight 返回當前屏幕高度(空白空間) window.screen.width 返回當前屏幕寬度(解析度值) window.screen.height 返回當前屏幕高度(解析度值 ...
  • 1 「喂飽」用戶的三個方法 最近,我看到有創業者開始為自己的用戶增長緩慢而發愁。 實際上,如果將自己的產品當成精心為用戶烹調的牛排,用戶吃一口就放下了餐具。這是火候的問題嗎?是調料問題嗎?還是擺盤裝飾的問題?......也許都不是,這個時候你更應該問自己一個問題:現在用戶是否正處於饑餓的狀態? 那飢 ...
  • 作者講解在Kotlin中Android擴展是如何替代 findViewById 的。 ...
  • fragment是Activity中用戶界面的一個行為或者是一部分。你可以在一個單獨的Activity上把多個Fragment組合成為一個多區域的UI,並且可以在多個Activity中再使用。你可以認為fragment是activity的一個模塊零件,它有自己的生命周期,接收它自己的輸入事件,並且可 ...
  • 如果要添加一個Notification,可以按照以下幾個步驟 1:獲取NotificationManager: NotificationManager m_NotificationManager=(NotificationManager)this.getSystemService(NOTIFICAT ...
  • Handler使用介紹: Handler根據接收的消息,處理UI更新。Thread線程發出消息,通知Handler更新UI。 Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg ...
  • iOS app記憶體分析套路 Xcode下查看app記憶體使用情況有2中方法: 一.Debug navigator中的Memory 此方法是查看記憶體最簡單直接有效的方法,真機調試時,通過Debug navigator中Memory查看app記憶體,入口如圖 根據這個值查看app記憶體占用,這個記憶體是當前ap ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...