安全的使用者驗證

為了保護您在 Android 的驗證系統,請考慮 密碼式模型,尤其是對於像使用者銀行 和電子郵件帳戶。提醒您,使用者安裝的某些應用程式 可能是為了騙取使用者

此外,請勿假設只有授權使用者會使用裝置。手機遭竊 是很常見的問題,而攻擊者會鎖定未鎖定的裝置,直接從中獲利 來自使用者資料或財務應用程式我們建議所有較為敏感的應用程式 合理的驗證逾時時間 (15 分鐘?) 和生物特徵辨識驗證, 需要通過額外身分驗證才能支付交易等敏感動作 傳輸。

生物特徵辨識驗證對話方塊

生物特徵辨識程式庫提供一組函式,用於顯示要求建立提示 臉部辨識或指紋辨識等生物特徵辨識驗證。 不過,生物特徵辨識提示可改回使用 LSKF, 已知的冒險風險對於敏感應用程式,建議 確認生物特徵辨識失敗後,會改回使用 PIN 碼驗證 且在用盡生物特徵辨識重試後 使用者可以等待、以密碼重新登入或重設帳戶。重設帳戶 根據使用者無法輕易在裝置上存取的因素 (最佳做法) )。

這項做法如何協助防範詐欺和手機遭竊

為防範詐欺行為有一種特別幫助 在進行交易前,在應用程式內進行生物特徵辨識驗證。當使用者 「進行金融交易」時,系統會顯示生物特徵辨識對話方塊 驗證交易確實是進行交易的指定使用者這個 無論攻擊者如何竊取裝置 攻擊者是否瞭解 LSKF,因為他們需要探測 擁有者。

如需更多安全防護,建議應用程式開發人員要求第 3 級 生物特徵辨識驗證,並使用 CryptoObject 處理銀行和 或以金融交易為例

實作

  1. 請務必納入 androidx.biometric 程式庫。
  2. 在保留活動或片段中加入生物特徵辨識登入對話方塊 您希望驗證使用者的邏輯。

Kotlin


private var executor: Executor? = null
private var biometricPrompt: BiometricPrompt? = null
private var promptInfo: BiometricPrompt.PromptInfo? = null

fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_login)
  executor = ContextCompat.getMainExecutor(this)
  biometricPrompt = BiometricPrompt(this@MainActivity,
    executor, object : AuthenticationCallback() {
      fun onAuthenticationError(
        errorCode: Int,
        @NonNull errString: CharSequence
      ) {
        super.onAuthenticationError(errorCode, errString)
        Toast.makeText(
          getApplicationContext(),
          "Authentication error: $errString", Toast.LENGTH_SHORT
        )
          .show()
      }

      fun onAuthenticationSucceeded(
        @NonNull result: BiometricPrompt.AuthenticationResult?
      ) {
        super.onAuthenticationSucceeded(result)
        Toast.makeText(
          getApplicationContext(),
          "Authentication succeeded!", Toast.LENGTH_SHORT
        ).show()
      }

      fun onAuthenticationFailed() {
        super.onAuthenticationFailed()
        Toast.makeText(
          getApplicationContext(), "Authentication failed",
          Toast.LENGTH_SHORT
        )
          .show()
      }
    })
  promptInfo = Builder()
    .setTitle("Biometric login for my app")
    .setSubtitle("Log in using your biometric credential")
    .setNegativeButtonText("Use account password")
    .build()

  // Prompt appears when user clicks "Log in".
  // Consider integrating with the keystore to unlock cryptographic operations,
  // if needed by your app.
  val biometricLoginButton: Button = findViewById(R.id.biometric_login)
  biometricLoginButton.setOnClickListener { view ->
    biometricPrompt.authenticate(
      promptInfo
    )
  }
}

Java


private Executor executor;
private BiometricPrompt biometricPrompt;
private BiometricPrompt.PromptInfo promptInfo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    executor = ContextCompat.getMainExecutor(this);
    biometricPrompt = new BiometricPrompt(MainActivity.this,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode,
                @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            Toast.makeText(getApplicationContext(),
                "Authentication error: " + errString, Toast.LENGTH_SHORT)
                .show();
        }

        @Override
        public void onAuthenticationSucceeded(
                @NonNull BiometricPrompt.AuthenticationResult result) {
            super.onAuthenticationSucceeded(result);
            Toast.makeText(getApplicationContext(),
                "Authentication succeeded!", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
            Toast.makeText(getApplicationContext(), "Authentication failed",
                Toast.LENGTH_SHORT)
                .show();
        }
    });

    promptInfo = new BiometricPrompt.PromptInfo.Builder()
            .setTitle("Biometric login for my app")
            .setSubtitle("Log in using your biometric credential")
            .setNegativeButtonText("Use account password")
            .build();

    // Prompt appears when the user clicks "Log in".
    // Consider integrating with the keystore to unlock cryptographic operations,
    // if needed by your app.
    Button biometricLoginButton = findViewById(R.id.biometric_login);
    biometricLoginButton.setOnClickListener(view -> {
            biometricPrompt.authenticate(promptInfo);
    });
}

最佳做法

建議您先從程式碼研究室開始,進一步瞭解生物特徵辨識。

您可以根據用途,在實作和不使用對話方塊的情況下實作對話方塊 明確的使用者操作為了避免詐欺,建議新增生物特徵辨識功能 內含明確的使用者操作對話方塊我們瞭解 新增 驗證功能可能會導致使用者體驗出現阻礙 銀行交易中處理的資訊,以及該生物特徵辨識 與其他驗證方式相比,Google 驗證更順暢 以便加入這個導覽層級

進一步瞭解生物特徵辨識驗證

密碼金鑰

密碼金鑰是比密碼更安全、更簡單的替代驗證方法。密碼金鑰用途 公開金鑰密碼編譯功能可讓使用者登入應用程式和網站 使用裝置的螢幕鎖定機制,例如指紋或臉孔 辨識。如此一來,使用者就不必費心記住及管理密碼。 同時大幅提高安全性

只要一個步驟,密碼金鑰就能滿足多重驗證的需求。 更換密碼和動態密碼,提供強大的防護 網路釣魚攻擊,並避免使用者在使用簡訊或應用程式時遭遇問題 密碼。由於密碼金鑰已標準化,因此單一實作即可 所有使用者都能享有無密碼的使用體驗裝置、瀏覽器和 以及作業系統

在 Android 裝置上使用 Credential Manager Jetpack 支援密碼金鑰 整合主要驗證方法 (包括密碼金鑰) 的程式庫 密碼和聯合登入 (例如「使用 Google 帳戶登入」)。

這項機制如何協助防範詐欺行為

密碼金鑰可防範網路釣魚攻擊,因為密碼金鑰只會在你的 已註冊的應用程式和網站。

密碼金鑰的核心元件是加密編譯金鑰。一般而言,這個 私密金鑰只會存放在您的裝置上,例如筆記型電腦或手機 並由憑證提供者 (又稱為密碼) 同步處理 管理員),例如 Google 密碼管理工具。只有對應的公開金鑰 儲存在線上服務所儲存的密碼金鑰。用於登入 會使用私密金鑰簽署公開金鑰的驗證要求。這個 來自您的某部裝置此外,為此,你必須 解鎖裝置或憑證存放區,防止未經授權的登入行為 (例如透過失竊的手機取得)。

在裝置遭竊且未鎖定的情況下,為防止他人未經授權擅自存取, 密碼金鑰必須與合理的驗證逾時期限搭配使用。一個 攻擊者竊取裝置的攻擊者時,不能只使用應用程式 因為先前的使用者已登入。相反地 每隔一段時間 (例如每 15 分鐘) 就會過期,且使用者應該 ,透過螢幕鎖定重新驗證來驗證身分。

如果手機遭竊,竊賊無法竊取您的 在其他裝置上使用的密碼 – 密碼金鑰專屬於特定裝置。如果您使用 Google 密碼管理工具和手機遭竊,可以登入 Google 其他裝置 (例如電腦) 上的帳戶,以及從遠端登出 遭竊。讓遭竊手機上的 Google 密碼管理工具 無法使用,包括任何已儲存的密碼金鑰。

在最糟糕的情況下,如果失竊的裝置未復原,密碼金鑰會 憑證提供者已建立並同步處理至新裝置 建立密碼金鑰。例如使用者可能已選擇 Google 密碼管理工具 建立密碼金鑰,使用者簽署金鑰後,就能在新裝置上存取密碼金鑰 重新登入 Google 帳戶,並提供先前使用的螢幕鎖定功能 裝置。

詳情請參閱 參閱「Google 密碼管理工具中密碼金鑰的安全性」一文。

實作

搭載 Android 9 (API 級別 28) 以上版本的裝置支援密碼金鑰。 Android 4.4 以上版本支援密碼和「使用 Google 帳戶登入」功能。目的地: 如要開始使用密碼金鑰,請按照下列步驟操作:

  1. 參考 Credential Manager 程式碼研究室,初步瞭解如何實作密碼金鑰。
  2. 詳閱密碼金鑰使用者體驗設計指南。本文件說明適合您的用途的建議流程。
  3. 按照指南學習 Credential Manager。
  4. 規劃應用程式的 Credential Manager 和密碼金鑰實作方式。規劃額外對 Digital Asset Links 的支援。

請參閱開發人員說明文件,進一步瞭解如何建立、註冊與 使用密碼金鑰進行驗證

安全重設帳戶

未經授權人士可以存取已解鎖裝置,例如手機 惡意應用程式) 會嘗試存取敏感的應用程式,尤其是銀行或現金應用程式。 如果應用程式實作生物特徵辨識驗證,攻擊者會嘗試重設 並登入該帳戶重設流程時,不可只依賴 例如電子郵件或簡訊動態密碼 重設連結。

以下是可納入應用程式重設的常見最佳做法 流程:

  • 臉部辨識和動態密碼
  • 安全性問題
  • 知識因素 (例如母親的婚前姓氏、出生城市或最愛) 歌曲)
  • 身分驗證程序

SMS Retriever API

SMS Retriever API 可讓你在 自動執行 Android 應用程式。如此一來,使用者 手動輸入驗證碼此外,這個 API 不會要求使用者 授予額外的潛在危險應用程式權限,例如 RECEIVE_SMSREAD_SMS。不過,簡訊不應做為唯一驗證的對象 防止他人在未經授權的情況下存取裝置。

這項機制如何協助防範詐欺行為

部分使用者只將簡訊驗證碼當做唯一的驗證方式, 輕鬆防範詐欺行為

SMS Retriever API 可讓應用程式直接擷取簡訊代碼,而不需要 並且提供一定程度的防詐欺機制。

實作

實作 SMS Retriever API 分為兩個部分:Android 和伺服器。

Android:(指南)

  1. 取得使用者的電話號碼。
  2. 啟動簡訊擷取程式用戶端。
  3. 將電話號碼傳送至你的伺服器。
  4. 接收驗證郵件。
  5. 將動態密碼傳送至您的伺服器。

伺服器:(指南)

  1. 建構驗證訊息。
  2. 透過簡訊傳送驗證訊息。
  3. 系統傳回動態密碼時進行驗證。

最佳做法

應用程式完成整合,並驗證使用者電話號碼後 SMS Retriever API 會嘗試取得動態密碼。如果成功的話,那就會是 表示自動已收到簡訊。否則 成功,且使用者需要手動輸入動態密碼,這可視為警告標誌 使用者可能遭遇詐欺

簡訊離開房間時,不應做為唯一的使用者驗證機制 不受本機攻擊的影響,例如入侵已解鎖裝置的攻擊者。或 SIM 卡 複製攻擊建議盡可能使用生物特徵辨識功能。啟用 裝置無法使用生物特徵辨識感應器,使用者驗證作業應 至少仰賴其中一個因素,不容易從目前裝置取得。

瞭解詳情

如要進一步瞭解最佳做法,請參閱下列資源: