2016-10-25 4 views
19

처음 등록 할 때 KeyPair을 생성하면 PrivateKey이 두 번째로 사용할 때 무효화됩니다. 이것은 단 한 번 발생합니다. 나는이 문제가있는 유일한 사람인가? 내 코드에 문제가 있습니까?Android 지문 API 및 개인/공개 키

PrivateKey을 사용하여 데이터에 서명 할 때 다른 키를 사용할 수 없습니다.

단계 :

  1. 모든 지문
  2. 등록
  3. KeyPair를 생성하고 영구적으로 무효가됩니다 FingerprintManager :: authenticate PrivateKey의 다음 사용시 FingerprintManager :: authenticate
  4. 를 사용하여 하나 개의 지문을 닦아주십시오. 이것은 단지 처음 내가 여기 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로 인증하면 키가 무효화됩니다. false로 setInvalidateByBiometricEnrollment를 사용하려고 시도했지만 도움이되었지만 안전하지 않습니다. – Toochka

+0

그러면 제조업체에서 사용하는 지문 소프트웨어의 버그 인 phonentoure를 사용하여 문제가 발생하는 것처럼 보였습니다. 제조사의 모든 전화기에서 동일한 결과가 나타 납니까? – JohanShogun

답변

1

전 이 link을 시도하고 완벽하게 작동합니다.

먼저 당신이 Mainfest에서 그림 같은를 생성

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

셋째

generateKey() 함수를

Image

두 번째 세트의 권한을 최소 SDK 모양을 설정해야 암호화 키는 장치에 안전하게 저장됩니다.

암호화 된 지문 관리자를 만드는 데 사용할 암호를 초기화하는 cipherInit() 함수입니다.

onCreate() 메서드 내에서 구현되는 인증 프로세스를 시작하기 전에 CryptoObject 인스턴스 및 다양한 기타 검사가 수행됩니다.

import android.Manifest; 
import android.annotation.TargetApi; 
import android.app.KeyguardManager; 
import android.content.pm.PackageManager; 
import android.hardware.fingerprint.FingerprintManager; 
import android.os.Build; 
import android.security.keystore.KeyGenParameterSpec; 
import android.security.keystore.KeyPermanentlyInvalidatedException; 
import android.security.keystore.KeyProperties; 
import android.support.v4.app.ActivityCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.widget.TextView; 
import java.io.IOException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.NoSuchProviderException; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.CertificateException; 
import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 


public class FingerprintActivity extends AppCompatActivity { 


    private KeyStore keyStore; 
    // Variable used for storing the key in the Android Keystore container 
    private static final String KEY_NAME = "androidHive"; 
    private Cipher cipher; 
    private TextView textView; 


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


     // Initializing both Android Keyguard Manager and Fingerprint Manager 
     KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); 
     FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE); 


     textView = (TextView) findViewById(R.id.errorText); 


     // Check whether the device has a Fingerprint sensor. 
     if(!fingerprintManager.isHardwareDetected()){ 
      /** 
      * An error message will be displayed if the device does not contain the fingerprint hardware. 
      * However if you plan to implement a default authentication method, 
      * you can redirect the user to a default authentication activity from here. 
      * Example: 
      * Intent intent = new Intent(this, DefaultAuthenticationActivity.class); 
      * startActivity(intent); 
      */ 
      textView.setText("Your Device does not have a Fingerprint Sensor"); 
     }else { 
      // Checks whether fingerprint permission is set on manifest 
      if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) { 
       textView.setText("Fingerprint authentication permission not enabled"); 
      }else{ 
       // Check whether at least one fingerprint is registered 
       if (!fingerprintManager.hasEnrolledFingerprints()) { 
        textView.setText("Register at least one fingerprint in Settings"); 
       }else{ 
        // Checks whether lock screen security is enabled or not 
        if (!keyguardManager.isKeyguardSecure()) { 
         textView.setText("Lock screen security not enabled in Settings"); 
        }else{ 
         generateKey(); 


         if (cipherInit()) { 
          FingerprintManager.CryptoObject cryptoObject = new FingerprintManager.CryptoObject(cipher); 
          FingerprintHandler helper = new FingerprintHandler(this); 
          helper.startAuth(fingerprintManager, cryptoObject); 
         } 
        } 
       } 
      } 
     } 
    } 


    @TargetApi(Build.VERSION_CODES.M) 
    protected void generateKey() { 
     try { 
      keyStore = KeyStore.getInstance("AndroidKeyStore"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


     KeyGenerator keyGenerator; 
     try { 
      keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore"); 
     } catch (NoSuchAlgorithmException | NoSuchProviderException e) { 
      throw new RuntimeException("Failed to get KeyGenerator instance", e); 
     } 


     try { 
      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 (NoSuchAlgorithmException | 
       InvalidAlgorithmParameterException 
       | CertificateException | IOException e) { 
      throw new RuntimeException(e); 
     } 
    } 


    @TargetApi(Build.VERSION_CODES.M) 
    public boolean cipherInit() { 
     try { 
      cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7); 
     } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
      throw new RuntimeException("Failed to get Cipher", e); 
     } 


     try { 
      keyStore.load(null); 
      SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, 
        null); 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      return true; 
     } catch (KeyPermanentlyInvalidatedException e) { 
      return false; 
     } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException | NoSuchAlgorithmException | InvalidKeyException e) { 
      throw new RuntimeException("Failed to init Cipher", e); 
     } 
    } 
} 

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)); 
     } 
    } 
} 

가 도움이 바랍니다.

0

당신은 GitHub의에서이 일을 볼 수 있습니다 : 그것은 당신을 도움이되기를 바랍니다 : 당신이 지문 데이터를 닦아 전에 설정 한 키를 다시 사용하려고 시도하는 것 같은 Confirm Credentials