2016-10-25 185 views
19

當我首先註冊並且只有指紋並生成KeyPair時,第二次使用PrivateKey時會失效。這隻發生一次。我是唯一有這個問題的人嗎?我的代碼有問題嗎?Android指紋API和私鑰/公鑰

我不能使用任何其他鍵,因爲我使用PrivateKey來簽署數據。

步驟:

  1. 擦拭所有指紋
  2. 登記一個指紋
  3. 生成KeyPair和使用FingerprintManager :: authenticate
  4. 在下次使用的FingerprintManager :: authenticate PrivateKey被永久失效。這種情況只有在第一次

下面,我產生了KeyPair

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keystore.load(null); 
KeyPairGenerator generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore"); 
generator.initialize(new KeyGenParameterSpec.Builder("key_name", KeyProperties.PURPOSE_SIGN) 
    .setDigests(digest) // I have defined digest before 
    .setSignaturePaddings(paddings) // I have defined paddings before 
    .setUserAuthenticationRequired(true) 
    .build()); 
generator.generateKeyPair(); 

而且這裏是我調用指紋身份驗證數據簽名的代碼的代碼:

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); 
keyStore.load(null); 
Signature signature = Signature.getInstance("signing_algorithm"); 
PrivateKey privateKey = (PrivateKey) keyStore.getKey("key_name", null); 
signature.initSign(privateKey); // Here I get KeyPermanentlyInvalidatedException 
CryptoObject crypto = new CryptoObject(signature); 
FingerprintManager fingerprintManager = context.getSystemService(FingerprintManager.class); 
CancellationSignal cancellationSignal = new CancellationSignal(); 
AuthenticationCallback authenticationCallback = new AuthenticationCallback() { 
    ... 
}; 
fingerprintManager.authenticate(crypto, cancelationSignal, 0, authenticationCallback, null); 
+0

我看來,像你試圖重用成立了你擦去指紋數據之前的關鍵。確保在擦拭指紋後重新設置密鑰。您可以嘗試將setInvalidatedByBiometricEnrollment設置爲false並查看會發生什麼, – JohanShogun

+0

首先,我擦除指紋,然後只註冊一個,生成密鑰。當我第一次使用生成的密鑰時,一切都按預期工作,但是當我用fingerpeint進行身份驗證以便第二次使用密鑰時,它將失效。我曾嘗試使用setInvalidateByBiometricEnrollment爲false,但它有幫助,但這不安全。 – Toochka

+0

那麼在我看來,這是一個使用手機軟件的手機使用的問題,製造商使用的指紋軟件中的問題是否會在製造商的所有手機上得到相同的結果? – JohanShogun

回答

1

我試試這個link並且完美地工作。

首先,您需要設置最小的SDK看起來像圖片

Image

第二套權限在Mainfest產生的

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

generateKey()函數加密密鑰然後安全地存儲在設備上。

cipherInit()函數,用於初始化將用於創建加密FingerprintManager的密碼。

CryptoObject實例以及在onCreate()方法內部實現的認證過程之前的各種其他檢查。

FingerPrintActivty.java

FingerprintAuthenticationHandler.Class

import android.Manifest; 
import android.app.Activity; 
import android.content.Context; 
import android.content.pm.PackageManager; 
import android.hardware.fingerprint.FingerprintManager; 
import android.os.CancellationSignal; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.widget.TextView; 


/** 
* Created by whit3hawks on 11/16/16. 
*/ 
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback { 


    private Context context; 


    // Constructor 
    public FingerprintHandler(Context mContext) { 
     context = mContext; 
    } 


    public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) { 
     CancellationSignal cancellationSignal = new CancellationSignal(); 
     if (ActivityCompat.checkSelfPermission(context, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 
     manager.authenticate(cryptoObject, cancellationSignal, 0, this, null); 
    } 


    @Override 
    public void onAuthenticationError(int errMsgId, CharSequence errString) { 
     this.update("Fingerprint Authentication error\n" + errString, false); 
    } 


    @Override 
    public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 
     this.update("Fingerprint Authentication help\n" + helpString, false); 
    } 


    @Override 
    public void onAuthenticationFailed() { 
     this.update("Fingerprint Authentication failed.", false); 
    } 


    @Override 
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { 
     this.update("Fingerprint Authentication succeeded.", true); 
    } 


    public void update(String e, Boolean success){ 
     TextView textView = (TextView) ((Activity)context).findViewById(R.id.errorText); 
     textView.setText(e); 
     if(success){ 
      textView.setTextColor(ContextCompat.getColor(context,R.color.colorPrimaryDark)); 
     } 
    } 
} 

希望它能幫助。