I'm trying to use a Signature object for signing AND verifying data using fingerprint authentication. It works fine for signing, but when it comes to verifying I get this error :
java.lang.IllegalArgumentException: Crypto primitive not backed by AndroidKeyStore provider: Signature object: SHA256withECDSA, spi: com.android.org.conscrypt.OpenSSLSignature$SHA256ECDSA@cf4a416
The exception is thrown not while generating the key (this part is fine) but when calling fingerprintManager.authenticate(cryptoObject, ...)
Basically this is how I generate a CryptoObject
instance :
KeyPairGenerator signatureKeyGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
signatureKeyGenerator.initialize(new KeyGenParameterSpec.Builder(keyName, KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA256)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
.setUserAuthenticationRequired(true)
.build());
KeyPair signatureKey = signatureKeyGenerator.generateKeyPair();
Signature signature = Signature.getInstance("SHA256withECDSA");
switch (MODE) {
case KeyProperties.PURPOSE_SIGN:
signature.initSign(signatureKey.getPrivate());
break;
case KeyProperties.PURPOSE_VERIFY:
KeyFactory factory = KeyFactory.getInstance(signatureKey.getPublic().getAlgorithm());
X509EncodedKeySpec spec = new X509EncodedKeySpec(signatureKey.getPublic().getEncoded());
PublicKey unrestrictedPublicKey = factory.generatePublic(spec);
signature.initVerify(unrestrictedPublicKey);
break;
}
CryptoObject cryptoObject new CryptoObject(signature);
I tried to add | KeyProperties.PURPOSE_VERIFY
to KeyGenParameterSpec.Builder
but it didn't work either and anyway that's how they do it in the official Google repo : https://github.com/googlesamples/android-AsymmetricFingerprintDialog (weird...)
Finally I tried to look into Android source code to see why the exception is thrown : AndroidKeyStoreProvider.java
Object spi = ((Signature) cryptoPrimitive).getCurrentSpi();
if (spi == null) {
throw new IllegalStateException("Crypto primitive not initialized");
} else if (!(spi instanceof KeyStoreCryptoOperation)) {
throw new IllegalArgumentException(
"Crypto primitive not backed by AndroidKeyStore provider: " + cryptoPrimitive
+ ", spi: " + spi);
}
But I can't even find the getCurrentSpi()
method...
Any help would be greatly appreciated !