Android 签名指纹认证
Android Fingerprint Authentication with Signature
我正在尝试使用 Signature 对象通过指纹身份验证对数据进行签名和验证。它可以很好地用于签名,但是在验证时出现此错误:
java.lang.IllegalArgumentException: Crypto primitive not backed by
AndroidKeyStore provider: Signature object:
SHA256withECDSA, spi:
com.android.org.conscrypt.OpenSSLSignature$SHA256ECDSA@cf4a416
不是在生成密钥时抛出异常(这部分没问题)而是在调用 fingerprintManager.authenticate(cryptoObject, ...)
时抛出异常
基本上这就是我生成 CryptoObject
实例的方式:
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);
我试图将 | KeyProperties.PURPOSE_VERIFY
添加到 KeyGenParameterSpec.Builder
但它也没有用,无论如何他们在官方 Google 回购协议中是这样做的:https://github.com/googlesamples/android-AsymmetricFingerprintDialog (奇怪...)
最后我试图查看 Android 源代码以了解抛出异常的原因: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);
}
但是我什至找不到getCurrentSpi()
方法...
如有任何帮助,我们将不胜感激!
在验证模式下,您正在使用 public 密钥初始化 Signature
实例,该密钥不是 Android 密钥库密钥。您的问题类似于
验证数字签名不是限制性操作,因为它是使用 public 密钥执行的,因此您真的不需要 FingerprintManager 和 CryptoObject
所以可以直接使用
signature.verify(sigToVerify)`
或使用 Android Keystore public key
初始化 Signature 对象
signature.initVerify(signatureKey.getPublic())
我正在尝试使用 Signature 对象通过指纹身份验证对数据进行签名和验证。它可以很好地用于签名,但是在验证时出现此错误:
java.lang.IllegalArgumentException: Crypto primitive not backed by AndroidKeyStore provider: Signature object: SHA256withECDSA, spi: com.android.org.conscrypt.OpenSSLSignature$SHA256ECDSA@cf4a416
不是在生成密钥时抛出异常(这部分没问题)而是在调用 fingerprintManager.authenticate(cryptoObject, ...)
基本上这就是我生成 CryptoObject
实例的方式:
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);
我试图将 | KeyProperties.PURPOSE_VERIFY
添加到 KeyGenParameterSpec.Builder
但它也没有用,无论如何他们在官方 Google 回购协议中是这样做的:https://github.com/googlesamples/android-AsymmetricFingerprintDialog (奇怪...)
最后我试图查看 Android 源代码以了解抛出异常的原因: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);
}
但是我什至找不到getCurrentSpi()
方法...
如有任何帮助,我们将不胜感激!
在验证模式下,您正在使用 public 密钥初始化 Signature
实例,该密钥不是 Android 密钥库密钥。您的问题类似于
验证数字签名不是限制性操作,因为它是使用 public 密钥执行的,因此您真的不需要 FingerprintManager 和 CryptoObject
所以可以直接使用
signature.verify(sigToVerify)`
或使用 Android Keystore public key
初始化 Signature 对象 signature.initVerify(signatureKey.getPublic())