hoc*_*yen 5 android private-key android-fingerprint-api
我使用 KeyPermanentlyInvalidatedException 来检测是否添加了新指纹。但它不会抛出 KeyPermanentlyInvalidatedException。
我试过这些步骤:
我也从 stackoverflow找到了这个链接,但它没有帮助我。
从文件:
一旦安全锁屏被禁用(重新配置为无、滑动或其他不对用户进行身份验证的模式)或当安全锁屏被强制重置(例如,由设备管理员)时,密钥将不可逆转地失效。此外,如果密钥要求每次使用密钥都进行用户身份验证,则一旦注册新指纹或不再注册指纹,它也将不可逆转地失效,除非使用 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();
}
}
Run Code Online (Sandbox Code Playgroud)
但是initSignature()函数总是返回 true。
| 归档时间: |
|
| 查看次数: |
1236 次 |
| 最近记录: |