在具有签名的应用程序中实现指纹认证

时间:2018-05-18 11:15:18

标签: android ecdsa android-fingerprint-api

我在运行android 6.0以下的应用程序时遇到了问题

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
    FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!fingerprintManager.isHardwareDetected()) {
            /**
             * An error message will be displayed if the device does not contain the fin.gerprint hardware.
             * However if you plan to implement a default authentication method,
             * you can redirect the user to a default authentication ctivity from here.
             * Example:
             * 
             */

        } else {


            // Checks whether fingerprint permission is set on manifest
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {

               // permission not granted
            } else {

                // Check whether at least one fingerprint is registered
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                    // Checks whether lock screen security is enabled or not
                    if (!keyguardManager.isKeyguardSecure()) {
                        // finger print not support

                    } else {

                        if (!fingerprintManager.hasEnrolledFingerprints()) {
                        // finger print not enrolled

                        } else {

                            /*Amit Verma  EC signature*/
                            createKeyPair();
                            if (initSignature()) {
                                ConstantDeclaration.mCryptoObject = new FingerprintManager.CryptoObject(mSignature);
                            }
                        }
                    }
                }
            }
        }
    }
}

以下是密钥对生成的代码

@TargetApi(Build.VERSION_CODES.M)
    private void createKeyPair() {
        // The enrolling flow for fingerprint. This is where you ask the user to set up fingerprint
        // for your flow. Use of keys is necessary if you need to know if the set of
        // enrolled fingerprints has changed.

        try {
            // Set the alias of the entry in Android KeyStore where the key will appear
            // and the constrains (purposes) in the constructor of the Builder

            KeyPairGenerator mKeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
            mKeyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(KEY_NAME,
                            KeyProperties.PURPOSE_SIGN)
                            .setDigests(KeyProperties.DIGEST_SHA1)
                            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                            // Require the user to authenticate with a fingerprint to authorize
                            // every use of the private key
//                            .setUserAuthenticationRequired(true)
                            .setUserAuthenticationRequired(false)
                            .build());
            mKeyPairGenerator.generateKeyPair();
        } catch (InvalidAlgorithmParameterException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }

    }

这是签名启动的代码。

 @TargetApi(Build.VERSION_CODES.M)
    private boolean initSignature() {
        try {
            mKeyStore = KeyStore.getInstance("AndroidKeyStore");
            mKeyStore.load(null);
            PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_NAME, null);
//            String strKey = Base64.encodeToString(key.getEncoded(),Base64.DEFAULT);

//            System.out.println("PrivateKey::"+strKey);
            mSignature = Signature.getInstance("SHA1withECDSA");
            mSignature.initSign(key);

            PublicKey publicKey = mKeyStore.getCertificate(KEY_NAME).getPublicKey();
            String strPublicKey = Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT);
            Singleton.getInstance().public_key_fp = strPublicKey;

            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            return false;
        } catch (Exception e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }/*catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
                | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }*/
    }

此代码工作正常,但是当我在Android 6.0下运行我的应用程序时,在启动应用程序时遇到异常。

Android version: 19
Device: samsung SM-J100ML
App version: 7
Line Number1: java.lang.Class.newInstanceImpl(Native Method)
Description : java.lang.VerifyError: launcherActivity
    at java.lang.Class.newInstanceImpl(Native Method)
    at java.lang.Class.newInstance(Class.java:1208)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
    at android.app.ActivityThread.access$800(ActivityThread.java:166)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5584)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
    at dalvik.system.NativeStart.main(Native Method)

我认为签名导入的问题是导入java.security.Signature;

1 个答案:

答案 0 :(得分:2)

我通过阅读logcat来解决问题,如上所述,

Could not find class 'android.security.keystore.KeyGenParameterSpec$Builder'

Could not find class 'android.hardware.fingerprint.FingerprintManager'

我在上面搜索了一下,发现了这个链接here

所以我删除了捕获阻止InvalidAlgorithmParameterException**KeyPermanentlyInvalidatedException**并替换为父类“异常”仅