From android marshmallow api 23 android supports fingerprint authentication support. Fingerprint api support android version 6.0 or greater.
Fingerprint authentication contains following process :
1. Check weather a user enabled keyguard or not in device.
2. Check weather permission to access fingerprint granted or not.
3. Check weather at least one fingerprint was entered or not.
4. Generate a private key with any blocking mode.
5. Initialize cypher with that key.
6. Start checking authentication with the key provided.
Following class can be use to set all the above steps :
public class MainActivity extends AppCompatActivity {
//Fingerprint manager class used to work with fingerprint hardware, like to check authentication success or failed etc.
private FingerprintManager fingerprintManager;
//Keyguard manger basically work on security level to check wheather user enabled pin, password or fingerprint or not.
private KeyguardManager keyguardManager;
//Keystore basically used to save key securely on the device.
private KeyStore keyStore;
//Key Generator is used to generate private key.
private KeyGenerator keyGenerator;
private static final String KEY_NAME = "example_key";
//Cipher is basically used encryption process.
private Cipher cipher;
private FingerprintManager.CryptoObject cryptoObject;
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
keyguardManager =(KeyguardManager) getSystemService(KEYGUARD_SERVICE);
fingerprintManager =(FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
//Checking wheather keyguard is enable or not.
if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this,"Lock screen security not enabled in Settings",Toast.LENGTH_LONG).show();
return;
}
//Cheking permission is granted or not.
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.USE_FINGERPRINT) !=PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Fingerprint authentication permission not enabled",Toast.LENGTH_LONG).show();
return;
}
//Chekcing wheather at least one fingerprint was enrolled or not.
if (!fingerprintManager.hasEnrolledFingerprints()) {
Toast.makeText(this,"Register at least one fingerprint in Settings",Toast.LENGTH_LONG).show();
return;
}
generateKey();
if (cipherInit()) {
cryptoObject = new FingerprintManager.CryptoObject(cipher);
FingerprintHandler helper = new FingerprintHandler(this);
helper.startAuth(fingerprintManager, cryptoObject);
}
}
@TargetApi(Build.VERSION_CODES.M)
protected void generateKey() {
try {
//instantiate keystore to store encypted key sucurely on the device with type of AndroidKeyStore.
keyStore = KeyStore.getInstance("AndroidKeyStore");
} catch (Exception e) {
e.printStackTrace();
}
try {
//instantiate keyGenerator to generate key with type of AndroidKeyStore and applying algo of Advanced Encryption Standard .
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES,"AndroidKeyStore");
} catch (NoSuchAlgorithmException |NoSuchProviderException e) {
throw new RuntimeException("Failed to get KeyGenerator instance", e);
}
try {
// Load keystore
keyStore.load(null);
// initialize key generator to generate a new key with the following properties that are :
//KeyGenParameterSpec.Builder is used to build key
// KeyProperties.PURPOSE_ENCRYPT |KeyProperties.PURPOSE_DECRYPT used to configure the key that can be used for both encryption and decryption.
//setBlockModes(KeyProperties.BLOCK_MODE_CBC) used to set block mode with which key can be used when encrypting like Cypher block chaining.
// setUserAuthenticationRequired(true) to set authentication with fingerprint everytime
//setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7) used to set the padding scheme when encrypting
// final build of key
keyGenerator.init(new
KeyGenParameterSpec.Builder(KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.build());
// Finally generate a secret key
keyGenerator.generateKey();
} catch (NoSuchAlgorithmException |InvalidAlgorithmParameterException| CertificateException | IOException e) {
throw new RuntimeException(e);
}
}
@TargetApi(Build.VERSION_CODES.M)
public boolean cipherInit() {
try {
//Initialize the cypher instance with same properties of key generator
cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
} catch (NoSuchAlgorithmException |
NoSuchPaddingException e) {
throw new RuntimeException("Failed to get Cipher", e);
}
try {
keyStore.load(null);
//get secret key generated by key generator.
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,null);
//Initialize the cypher with key.
cipher.init(Cipher.ENCRYPT_MODE, key);
return true;
} catch (KeyPermanentlyInvalidatedException e) {
return false;
} catch (KeyStoreException | CertificateException
| UnrecoverableKeyException | IOException
| NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Failed to init Cipher", e);
}
}
}
Finger print handler class to start and check fingerprint authorization with the secret key:
@TargetApi(Build.VERSION_CODES.M)
public class FingerprintHandler extends FingerprintManager.AuthenticationCallback {
private CancellationSignal cancellationSignal;
private Context appContext;
public FingerprintHandler(Context context) {
appContext = context;
}
// Start authenticate fingerprint.
public void startAuth(FingerprintManager manager,
FingerprintManager.CryptoObject cryptoObject) {
cancellationSignal = new CancellationSignal();
if (ActivityCompat.checkSelfPermission(appContext,Manifest.permission.USE_FINGERPRINT) !=PackageManager.PERMISSION_GRANTED) {
return;
}
manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
}
@Override
public void onAuthenticationError(int errMsgId,
CharSequence errString) {
Toast.makeText(appContext,"Authentication error\n" + errString,Toast.LENGTH_LONG).show();
}
@Override
public void onAuthenticationHelp(int helpMsgId,
CharSequence helpString) {
Toast.makeText(appContext,"Authentication help\n" + helpString,Toast.LENGTH_LONG).show();
}
@Override
public void onAuthenticationFailed() {
Toast.makeText(appContext,"Authentication failed.",Toast.LENGTH_LONG).show();
}
@Override
public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
Toast.makeText(appContext,"Authentication succeeded.",Toast.LENGTH_LONG).show();
}
}
0 Comment(s)