為保護 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。
- 為應用程式規劃憑證管理工具和密碼金鑰的實作方式,並規劃新增 Digital Asset Links 的支援。
如要進一步瞭解如何建立、註冊及驗證密碼金鑰,請參閱開發人員說明文件。
安全重設帳戶
如果未經授權的攻擊者能存取已解鎖的裝置 (例如搶走手機),就會嘗試存取機密應用程式,尤其是銀行或現金應用程式。如果應用程式實作生物特徵辨識驗證,攻擊者會嘗試重設帳戶以入侵。帳戶重設流程不應只依賴裝置上容易取得的資訊,例如電子郵件或簡訊 OTP 重設連結。
以下是常見的最佳做法,可納入應用程式的重設流程:
- 臉部辨識 (除了 OTP 之外)
- 安全性問題
- 知識因素 (例如母親的本姓、出生城市或喜愛的歌曲)
- 身分驗證程序
SMS Retriever API
SMS Retriever API 可讓您在 Android 應用程式中自動執行簡訊驗證。這樣一來,使用者就不必手動輸入驗證碼。此外,這項 API 不會要求使用者提供額外權限,也不會要求可能不安全的應用程式權限,例如 RECEIVE_SMS
或 READ_SMS
。不過,簡訊不應做為唯一的驗證方式,以防裝置遭未經授權的本機存取。
這項功能如何協助防範詐欺
部分使用者只採用簡訊驗證碼做為驗證要素,這會讓詐欺者有機可乘。
應用程式可透過 SMS Retriever API 直接擷取簡訊驗證碼,不必與使用者互動,並提供一定程度的詐欺防護。
實作
導入 SMS Retriever API 的流程分為兩個部分:Android 和伺服器。
Android:(指南)
- 取得使用者的電話號碼。
- 啟動 SMS 擷取器用戶端。
- 將電話號碼傳送至伺服器。
- 接收驗證訊息。
- 將 OTP 傳送至伺服器。
伺服器:(指南)
- 建構驗證訊息。
- 透過簡訊傳送驗證訊息。
- 系統傳回 OTP 時,請驗證該 OTP。
最佳做法
整合應用程式並使用 SMS Retriever API 驗證使用者電話號碼後,系統會嘗試取得動態密碼。如果成功,這就是簡訊在裝置上自動收到的強烈信號。如果驗證失敗,使用者必須手動輸入一次性密碼,這可能是使用者遭遇詐欺的警訊。
簡訊不應做為唯一的使用者驗證機制,因為這類機制容易受到本地攻擊,例如攻擊者竊取未解鎖的裝置,或是進行 SIM 卡複製攻擊。建議盡可能使用生物特徵辨識。如果裝置沒有生物特徵辨識感應器,使用者驗證應至少採用一種不易從目前裝置取得的因素。
瞭解詳情
如要進一步瞭解最佳做法,請參閱下列資源: