Как дождаться, пока biometricPrompt.authentication (promptInfo, cryptoObject) завершит задачу аутентификации в функции? - PullRequest
1 голос
/ 08 июля 2020

Я пишу знаковую функцию Android, которая принимает открытый текст byte [] и возвращает подпись byte []. Он использует частный защищенный элемент от телефона Android для подписи, что требует аутентификации Biometri c (biometricPrompt.authentication).

Я пробовал много способов сделать это, но каждый раз это терпит неудачу. В приведенном ниже коде не отображается приглашение Biometri c во время выполнения, оно просто зависает на главном экране из-за biometricPrompt.wait (). Я много искал решение, но не нашел. Пожалуйста помоги. :)

  private MainActivityTest mainAct = null;
  private byte[] sig = null;

  public AndroidSecureElement(MainActivity mainAct){
    this.mainAct = mainAct;
  }

  public byte[] signSE(final String alias, final byte[] plaintext) throws Exception {
    final Executor executor;
    final BiometricPrompt biometricPrompt;
    final BiometricPrompt.PromptInfo promptInfo;

    KeyStore keyStore = null;
    final Signature s;
    PrivateKey privKey = null;

    keyStore = KeyStore.getInstance("AndroidKeyStore");
    keyStore.load(null);

    privKey = (PrivateKey)keyStore.getKey(alias, null);

    if(privKey.getAlgorithm().equalsIgnoreCase("RSA")){
        s = Signature.getInstance("SHA256withRSA");
    }
    else if(privKey.getAlgorithm().equalsIgnoreCase("EC")){
        s = Signature.getInstance("SHA256withECDSA");
    }
    else{
        throw new Exception("Sign Failed: Unknown Algorithm found: "+privKey.getAlgorithm());
    }

    privKey = (PrivateKey)keyStore.getKey(alias, null);
    s.initSign(privKey);

    executor = ContextCompat.getMainExecutor(mainAct);
    biometricPrompt = new BiometricPrompt(mainAct,
            executor, new BiometricPrompt.AuthenticationCallback() {
        @Override
        public void onAuthenticationError(int errorCode,
                                          @NonNull CharSequence errString) {
            super.onAuthenticationError(errorCode, errString);
            Toast.makeText(mainAct.getApplicationContext(),
                    "Authentication error: " + errString, Toast.LENGTH_SHORT)
                    .show();
            this.notify();
        }

        @Override
        public void onAuthenticationSucceeded(
                @NonNull BiometricPrompt.AuthenticationResult result) {

            super.onAuthenticationSucceeded(result);
            Toast.makeText(mainAct.getApplicationContext(),
                    "Authentication succeeded!", Toast.LENGTH_SHORT).show();

            try {
                Signature s = result.getCryptoObject().getSignature();
                s.update(plaintext);
                sig = s.sign();
            } catch (Exception e) {
                Toast.makeText(mainAct.getApplicationContext(),
                        "Sign failed!", Toast.LENGTH_SHORT).show();
            }
            finally{
                this.notify();
            }
        }

        @Override
        public void onAuthenticationFailed() {
            super.onAuthenticationFailed();
            Toast.makeText(mainAct.getApplicationContext(), "Authentication failed",
                    Toast.LENGTH_SHORT)
                    .show();
            this.notify();
        }
    });

    promptInfo = new BiometricPrompt.PromptInfo.Builder()
            .setTitle("Biometric login for Secure Element access")
            .setSubtitle("Log in using your biometric credential")
            .setNegativeButtonText("Cancel")
            .setConfirmationRequired(true)
            .build()
    ;

    biometricPrompt.authenticate(promptInfo, new BiometricPrompt.CryptoObject(s));

    synchronized (biometricPrompt) {
        biometricPrompt.wait();
    }

    return sig;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...