為保護 Android 中的驗證系統,請考慮改用其他密碼模型,尤其是對於使用者的銀行和電子郵件帳戶這類敏感帳戶。提醒您,使用者安裝的某些應用程式可能沒有最好的意圖,也可能試圖騙取使用者。
此外,請勿假設只有授權使用者會使用裝置。手機盜竊是常見的問題,攻擊者會鎖定未鎖定的裝置,直接透過使用者資料或金融應用程式營利。我們建議所有敏感的應用程式都採用合理的驗證逾時時間 (15 分鐘?),並需要進行生物特徵辨識驗證,且需要先完成額外的驗證程序,才能進行匯款等敏感動作。
生物特徵辨識驗證對話方塊
生物特徵辨識程式庫提供一組函式,用於顯示要求生物特徵辨識驗證的提示,例如臉部辨識或指紋辨識。不過,生物特徵辨識提示可設為改回使用 LSKF,後者俱有已知的應接字元瀏覽風險。針對敏感的應用程式,我們建議不要讓生物特徵辨識功能改回使用 PIN 碼,而且使用者用完生物特徵辨識重試後,即可等待,或以密碼重新登入或重設帳戶。重設帳戶時,應要求裝置無法輕易存取的因素 (最佳做法如下)。
這項做法如何協助防範詐欺和手機遭竊
預防詐欺的特定使用案例是,在交易前要求在應用程式中要求生物特徵辨識驗證。當使用者想進行金融交易時,系統會顯示生物特徵辨識對話方塊,用於驗證交易的確實是進行交易的指定使用者。無論攻擊者是否知道 LSKF,這項最佳做法都能防範攻擊者竊取裝置,因為他們需要探測他們是裝置的擁有者。
為了提高安全性,建議應用程式開發人員要求使用第 3 級生物特徵辨識驗證,並使用 CryptoObject
進行銀行和金融交易。
導入作業
- 請務必納入 androidx.biometric 程式庫。
- 在活動或片段中加入生物特徵辨識登入對話方塊,其中保留您要驗證使用者的邏輯。
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); }); }
最佳做法
建議您先從程式碼研究室開始,進一步瞭解生物特徵辨識。
視用途而定,無論使用者是否有明確操作,您都可以實作對話方塊。為防範詐欺行為,建議您新增生物特徵辨識對話方塊,並在每筆交易中明確提供使用者明確的操作動作。我們瞭解新增驗證機制會對使用者體驗帶來阻礙,但由於銀行交易中要處理的資訊性質,且生物特徵辨識驗證作業比其他驗證方法更順暢,我們認為必須新增這種瀏覽機制。
密碼金鑰
密碼金鑰是比密碼更安全、更簡單的替代驗證方法。密碼金鑰採用公開金鑰密碼編譯技術,讓使用者能夠使用裝置的螢幕鎖定機制 (例如指紋或臉部辨識) 登入應用程式和網站。這樣使用者就不必費心記住及管理密碼,安全性大幅提升。
只要一個步驟,密碼金鑰就能滿足多重驗證的要求。這個機制會取代密碼和動態密碼,因此能有效防範網路釣魚攻擊,避免使用簡訊或應用程式的動態密碼,導致使用者體驗大打折扣。由於密碼金鑰已標準化,因此單一實作可讓所有使用者的裝置、瀏覽器和作業系統享有無密碼的使用體驗。
在 Android 上,系統會使用 Credential Manager Jetpack 程式庫支援密碼金鑰,該程式庫整合主要驗證方法,包括密碼金鑰、密碼和聯合登入 (例如「使用 Google 帳戶登入」)。
這項機制如何協助防範詐欺行為
密碼金鑰只能用於您註冊的應用程式和網站,因此可防範網路釣魚攻擊。
密碼金鑰的核心元件是加密編譯金鑰。一般來說,這個私密金鑰只會儲存在您的裝置上 (例如筆電或手機),並會透過 Google 密碼管理工具等憑證提供者 (又稱為密碼管理工具) 同步處理到這些裝置上。建立密碼金鑰時,線上服務只會儲存對應的公開金鑰。服務會在登入時使用私密金鑰,透過公開金鑰簽署驗證要求。這可能來自您的其中一部裝置。此外,您必須解鎖裝置或憑證存放區,防止未經授權的登入行為 (例如透過失竊的手機登入)。
為避免在裝置遭竊且已解鎖的情況下發生未經授權的存取行為,密碼金鑰必須與合理的驗證逾時期限結合。因為上一個使用者已經登入,竊取裝置的攻擊者不得使用應用程式。憑證應以固定間隔 (例如每 15 分鐘) 到期,使用者也應要求透過螢幕鎖定重新驗證來驗證身分。
如果手機遭竊,密碼金鑰可保護資料安全,因為竊賊無法竊取密碼,進而使用其他裝置使用 (密碼金鑰會視裝置而異)。如果您使用 Google 密碼管理工具,但手機遭竊,可以使用其他裝置 (例如電腦) 登入 Google 帳戶,然後從遠端從遭竊的手機中登出。這會導致失竊手機上的 Google 密碼管理工具無法使用,包括任何已儲存的密碼金鑰。
在最壞的情況下,如果失竊的裝置未復原,建立並同步密碼金鑰的憑證提供者會把密碼金鑰同步處理回新裝置。舉例來說,使用者可能會選擇使用 Google 密碼管理工具建立密碼金鑰,這時只要重新登入 Google 帳戶,並提供舊裝置的螢幕鎖定功能,就能在新裝置上存取密碼金鑰。
詳情請參閱「Google 密碼管理工具中的密碼金鑰安全性」一文。
導入作業
搭載 Android 9 (API 級別 28) 以上版本的裝置支援密碼金鑰。Android 4.4 以上版本支援密碼和「使用 Google 帳戶登入」功能。如要開始使用密碼金鑰,請按照下列步驟操作:
- 參考 Credential Manager 程式碼研究室,初步瞭解如何實作密碼金鑰。
- 詳閱密碼金鑰使用者體驗設計指南。本文件說明適合您的用途的建議流程。
- 按照指南學習 Credential Manager。
- 規劃應用程式的 Credential Manager 和密碼金鑰實作方式,規劃新增 Digital Asset Links 支援功能。
如要進一步瞭解如何建立、註冊密碼金鑰,以及使用密碼金鑰進行驗證,請參閱開發人員說明文件。
安全重設帳戶
未經授權人士可以存取已解鎖裝置 (例如偷竊手機時),會嘗試存取敏感應用程式,尤其是銀行或現金應用程式。如果應用程式實作生物特徵辨識驗證,攻擊者會嘗試重設帳戶才能進入。重設流程時,不可僅仰賴裝置上可輕鬆存取的資訊,例如電子郵件或簡訊動態密碼重設連結。
以下是可納入應用程式重設流程的常見最佳做法:
- 臉部辨識和動態密碼
- 安全提示問題
- 知識因素 (例如母親的婚前姓氏、城市或最喜歡的歌曲)
- 身分驗證程序
SMS Retriever API
SMS Retriever API 可讓您在 Android 應用程式中自動執行簡訊的使用者驗證。如此一來,使用者就不需要手動輸入驗證碼。此外,這個 API 不會要求使用者授予其他可能危險的應用程式權限,例如 RECEIVE_SMS
或 READ_SMS
。不過,請勿將簡訊當做唯一使用者驗證機制,以避免在未經授權的情況下存取裝置。
這項機制如何協助防範詐欺行為
部分使用者會使用簡訊代碼做為唯一的驗證方式,為詐欺的進入點提供簡便的進入點。
SMS Retriever API 可讓應用程式不需使用者互動即直接擷取簡訊代碼,並且提供防範詐欺的保護措施。
導入作業
實作 SMS Retriever API 分為兩個部分:Android 和伺服器。
Android:(指南)
- 取得使用者的電話號碼。
- 啟動簡訊擷取程式用戶端。
- 將電話號碼傳送至你的伺服器。
- 接收驗證郵件。
- 將動態密碼傳送至您的伺服器。
伺服器:(指南)
- 建構驗證訊息。
- 透過簡訊傳送驗證訊息。
- 系統傳回動態密碼時進行驗證。
最佳做法
應用程式整合完成,且使用者電話號碼通過 SMS Retriever API 驗證後,就會嘗試取得動態密碼。如果傳送成功,表示簡訊會自動收到在裝置上。如果要求未成功,且使用者必須手動輸入動態密碼,則這可能是警告徵兆,表示使用者可能遇到詐欺。
請勿利用簡訊做為唯一的使用者驗證機制,因為這類機制可以留下本機攻擊空間,例如入侵已解鎖裝置的攻擊者;或是 SIM 卡複製攻擊。建議盡可能使用生物特徵辨識功能。在無法使用生物特徵辨識感應器的裝置上,使用者驗證作業應仰賴至少一個難以從目前裝置取得的因素。
瞭解詳情
如要進一步瞭解最佳做法,請參閱下列資源: