KeyPermanentlyInvalidatedException无效

时间:2018-05-27 05:58:24

标签: android private-key android-fingerprint-api

我使用KeyPermanentlyInvalidatedException来检测添加了新指纹。但它并没有抛出KeyPermanentlyInvalidatedException。

我尝试了这些步骤:

  1. 列表项
  2. 创建密钥对
  3. 从私钥初始签名
  4. 从手机设置
  5. 添加新指纹
  6. 再次尝试从私钥初始签名 但它并没有抛出KeyPermanentlyInvalidatedException
  7. 我也从stackoverflow中找到了这个link,但它对我没有帮助。

    来自文件:

      

    一旦禁用安全锁定屏幕(重新配置为无,刷卡或其他未对用户进行身份验证的模式)或强制重置安全锁定屏幕(例如,由设备管理员),密钥将变为不可逆转无效。此外,如果密钥要求每次使用密钥时都进行用户身份验证,则一旦注册新指纹或一旦不再注册指纹,它也会不可逆转地无效,除非在注册后使用setInvalidatedByBiometricEnrollment(boolean)来允许有效性。尝试使用此类密钥初始化加密操作将导致KeyPermanentlyInvalidatedException。

    这是我的代码:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_authenticate);
    
        mButtonTest = findViewById(R.id.button_test);
        mButtonTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonTestOnClick();
            }
        });
    
        boolean isFirstTime = PreferenceManager.getInstances().getFirstTime();
        PreferenceManager.getInstances().setFirstTime(false);
    
        if (isFirstTime) {
            createKeyPair();
        }
    }
    
    private void buttonTestOnClick() {
        boolean result = initSignature();
        Log.e("iii", "Create signature result: " + result);
    
        boolean isFirstTime = PreferenceManager.getInstances().getFirstTime();
    
        if (result) {
            if (isFirstTime) {
                enroll();
            }
            startListening();
        }
    }
    
    
    /**
     * Generates an asymmetric key pair in the Android Keystore. Every use of the private key must
     * be authorized by the user authenticating with fingerprint. Public key use is unrestricted.
     */
    public void createKeyPair() {
        try {
            mKeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new RuntimeException("Failed to get an instance of KeyPairGenerator", e);
        }
    
        // 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
            mKeyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(KEY_NAME,
                            KeyProperties.PURPOSE_SIGN)
                            .setDigests(KeyProperties.DIGEST_SHA256)
                            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                            // Require the user to authenticate with a fingerprint to authorize
                            // every use of the private key
                            .setUserAuthenticationRequired(true)
                            .build());
            mKeyPairGenerator.generateKeyPair();
        } catch (InvalidAlgorithmParameterException e) {
            throw new RuntimeException(e);
        }
    }
    
    
    /**
     * Initialize the {@link Signature} instance with the created key in the
     * {@link #createKeyPair()} method.
     *
     * @return {@code true} if initialization is successful, {@code false} if the lock screen has
     * been disabled or reset after the key was generated, or if a fingerprint got enrolled after
     * the key was generated.
     */
    private boolean initSignature() {
        // Create keystore
        try {
            mKeyStore = KeyStore.getInstance("AndroidKeyStore");
        } catch (KeyStoreException e) {
            throw new RuntimeException("Failed to get an instance of KeyStore", e);
        }
    
        // Create signature
        try {
            mSignature = Signature.getInstance("SHA256withECDSA");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to get an instance of Signature", e);
        }
    
    
        try {
            mKeyStore.load(null);
            PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_NAME, null);
            mSignature.initSign(key);
            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            return false;
        } catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
                | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }
    }
    
    
    private void enroll() {
        try {
            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
            PublicKey publicKey = keyStore.getCertificate(AuthenticateActivity.KEY_NAME).getPublicKey();
            // Provide the public key to the backend. In most cases, the key needs to be transmitted
            // to the backend over the network, for which Key.getEncoded provides a suitable wire
            // format (X.509 DER-encoded). The backend can then create a PublicKey instance from the
            // X.509 encoded form using KeyFactory.generatePublic. This conversion is also currently
            // needed on API Level 23 (Android M) due to a platform bug which prevents the use of
            // Android Keystore public keys when their private keys require user authentication.
            // This conversion creates a new public key which is not backed by Android Keystore and
            // thus is not affected by the bug.
            KeyFactory factory = KeyFactory.getInstance(publicKey.getAlgorithm());
            X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey.getEncoded());
            PublicKey verificationKey = factory.generatePublic(spec);
            //mStoreBackend.enroll("user", "password", verificationKey);
        } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException |
                IOException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }
    

    initSignature()函数allways返回true。

0 个答案:

没有答案