Android指纹API和私钥/公钥 [英] Android Fingerprint API and Private/Public keys

查看:142
本文介绍了Android指纹API和私钥/公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我第一次注册并且只有指纹并生成KeyPair时,当我第二次使用它时,PrivateKey将失效.这只会发生一次.我是唯一一个遇到此问题的人吗?我的代码有问题吗?

When I enrol first and only fingerprint and generate KeyPair the PrivateKey gets invalidated when I use it for the second time. This happens only once. Am I the only one having this issue? Is there something wrong with my code?

我无法使用任何其他密钥,因为我正在使用PrivateKey签名数据.

I cannot use any other key as I'm using PrivateKey to sign data.

步骤:

  1. 擦拭所有指纹
  2. 注册一个指纹
  3. 生成KeyPair并使用FingerprintManager :: authenticate
  4. 在下一次使用FingerprintManager :: authenticate PrivateKey的过程中将永久失效.这仅是第一次发生
  1. Wipe all fingerprints
  2. Enrol one fingerprint
  3. Generate KeyPair and use FingerprintManager :: authenticate
  4. During next use of FingerprintManager :: authenticate PrivateKey gets permanently invalidated. This happens only for the first time

在生成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();

这是我调用指纹身份验证进行数据签名的代码:

And here is the code where I invoke fingerprint authentication for data signing:

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

推荐答案

我尝试使用此

i try this link and work perfectly .

首先,您需要将最小sdk设置为图片

First you need to set Minimum sdk look like the Picture

Mainfest中的第二个权限

Second set Permission in Mainfest

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

第三

generateKey()函数生成一个加密密钥,然后将其安全地存储在设备上.

generateKey() function which generates an encryption key which is then stored securely on the device.

cipherInit()函数,用于初始化将用于创建加密的FingerprintManager的密码.

cipherInit() function that initializes the cipher that will be used to create the encrypted FingerprintManager.

在启动在onCreate()方法内部实现的身份验证过程之前,CryptoObject实例和各种其他检查.

CryptoObject instance and various other checks before initiating the authentication process which is implemented inside onCreate() method.

FingerPrintActivty.java

FingerPrintActivty.java

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

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

希望有帮助.

这篇关于Android指纹API和私钥/公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆