在带有签名的应用程序中实现指纹认证
Implemented Finger Print Authentication in Application with signature
当 运行 低于 android 6.0
的应用程序时,我遇到了问题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!fingerprintManager.isHardwareDetected()) {
/**
* An error message will be displayed if the device does not contain the fin.gerprint hardware.
* However if you plan to implement a default authentication method,
* you can redirect the user to a default authentication ctivity from here.
* Example:
*
*/
} else {
// Checks whether fingerprint permission is set on manifest
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
// permission not granted
} else {
// Check whether at least one fingerprint is registered
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Checks whether lock screen security is enabled or not
if (!keyguardManager.isKeyguardSecure()) {
// finger print not support
} else {
if (!fingerprintManager.hasEnrolledFingerprints()) {
// finger print not enrolled
} else {
/*Amit Verma EC signature*/
createKeyPair();
if (initSignature()) {
ConstantDeclaration.mCryptoObject = new FingerprintManager.CryptoObject(mSignature);
}
}
}
}
}
}
}
}
这是密钥对生成的代码
@TargetApi(Build.VERSION_CODES.M)
private void createKeyPair() {
// 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
KeyPairGenerator mKeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
mKeyPairGenerator.initialize(
new KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA1)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
// Require the user to authenticate with a fingerprint to authorize
// every use of the private key
// .setUserAuthenticationRequired(true)
.setUserAuthenticationRequired(false)
.build());
mKeyPairGenerator.generateKeyPair();
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
}
这里是签名启动的代码。
@TargetApi(Build.VERSION_CODES.M)
private boolean initSignature() {
try {
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
mKeyStore.load(null);
PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_NAME, null);
// String strKey = Base64.encodeToString(key.getEncoded(),Base64.DEFAULT);
// System.out.println("PrivateKey::"+strKey);
mSignature = Signature.getInstance("SHA1withECDSA");
mSignature.initSign(key);
PublicKey publicKey = mKeyStore.getCertificate(KEY_NAME).getPublicKey();
String strPublicKey = Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT);
Singleton.getInstance().public_key_fp = strPublicKey;
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (Exception e) {
throw new RuntimeException("Failed to init Cipher", e);
}/*catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}*/
}
这段代码工作正常,但是当我 运行 我的应用程序低于 Android 6.0 时,在启动应用程序时出现异常。
Android version: 19
Device: samsung SM-J100ML
App version: 7
Line Number1: java.lang.Class.newInstanceImpl(Native Method)
Description : java.lang.VerifyError: launcherActivity
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
at android.app.ActivityThread.access0(ActivityThread.java:166)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5584)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
我认为签名导入的问题是导入 java.security.Signature;
我通过阅读 logcat 上面的评论找到了问题,
Could not find class 'android.security.keystore.KeyGenParameterSpec$Builder'
和
Could not find class 'android.hardware.fingerprint.FingerprintManager'
我在 classes 上面进行了谷歌搜索,发现了这个 link
所以我 删除了 捕获块 InvalidAlgorithmParameterException
,**KeyPermanentlyInvalidatedException**
并替换为 parent class "Exception"只有.
当 运行 低于 android 6.0
的应用程序时,我遇到了问题if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
FingerprintManager fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!fingerprintManager.isHardwareDetected()) {
/**
* An error message will be displayed if the device does not contain the fin.gerprint hardware.
* However if you plan to implement a default authentication method,
* you can redirect the user to a default authentication ctivity from here.
* Example:
*
*/
} else {
// Checks whether fingerprint permission is set on manifest
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) {
// permission not granted
} else {
// Check whether at least one fingerprint is registered
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Checks whether lock screen security is enabled or not
if (!keyguardManager.isKeyguardSecure()) {
// finger print not support
} else {
if (!fingerprintManager.hasEnrolledFingerprints()) {
// finger print not enrolled
} else {
/*Amit Verma EC signature*/
createKeyPair();
if (initSignature()) {
ConstantDeclaration.mCryptoObject = new FingerprintManager.CryptoObject(mSignature);
}
}
}
}
}
}
}
}
这是密钥对生成的代码
@TargetApi(Build.VERSION_CODES.M)
private void createKeyPair() {
// 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
KeyPairGenerator mKeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
mKeyPairGenerator.initialize(
new KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_SIGN)
.setDigests(KeyProperties.DIGEST_SHA1)
.setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
// Require the user to authenticate with a fingerprint to authorize
// every use of the private key
// .setUserAuthenticationRequired(true)
.setUserAuthenticationRequired(false)
.build());
mKeyPairGenerator.generateKeyPair();
} catch (InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
}
这里是签名启动的代码。
@TargetApi(Build.VERSION_CODES.M)
private boolean initSignature() {
try {
mKeyStore = KeyStore.getInstance("AndroidKeyStore");
mKeyStore.load(null);
PrivateKey key = (PrivateKey) mKeyStore.getKey(KEY_NAME, null);
// String strKey = Base64.encodeToString(key.getEncoded(),Base64.DEFAULT);
// System.out.println("PrivateKey::"+strKey);
mSignature = Signature.getInstance("SHA1withECDSA");
mSignature.initSign(key);
PublicKey publicKey = mKeyStore.getCertificate(KEY_NAME).getPublicKey();
String strPublicKey = Base64.encodeToString(publicKey.getEncoded(), Base64.DEFAULT);
Singleton.getInstance().public_key_fp = strPublicKey;
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (Exception e) {
throw new RuntimeException("Failed to init Cipher", e);
}/*catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}*/
}
这段代码工作正常,但是当我 运行 我的应用程序低于 Android 6.0 时,在启动应用程序时出现异常。
Android version: 19
Device: samsung SM-J100ML
App version: 7
Line Number1: java.lang.Class.newInstanceImpl(Native Method)
Description : java.lang.VerifyError: launcherActivity
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
at android.app.ActivityThread.access0(ActivityThread.java:166)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5584)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
我认为签名导入的问题是导入 java.security.Signature;
我通过阅读 logcat 上面的评论找到了问题,
Could not find class 'android.security.keystore.KeyGenParameterSpec$Builder'
和
Could not find class 'android.hardware.fingerprint.FingerprintManager'
我在 classes 上面进行了谷歌搜索,发现了这个 link
所以我 删除了 捕获块 InvalidAlgorithmParameterException
,**KeyPermanentlyInvalidatedException**
并替换为 parent class "Exception"只有.