Android fingerprint unlock

public class FingerprintActivity extends Activity implements OnClickListener {

    private FingerprintManager manager;
    private CancellationSignal signal;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fingerprint);
        findViewById(R.id.Fingerprint).setOnClickListener(this);
        manager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
    }

    @SuppressLint("NewApi")
    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {
        case R.id.Fingerprint:

            if (!manager.isHardwareDetected()) {
                Toast.makeText(this, "设备不支持", Toast.LENGTH_LONG).show();
                return;
            }
            KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
            if (!keyguardManager.isKeyguardSecure()) {
                Toast.makeText(this, "请设置图案锁", Toast.LENGTH_LONG).show();
                return;
            }
            if (!manager.hasEnrolledFingerprints()) {
                Toast.makeText(this, "请设置指纹", Toast.LENGTH_LONG).show();
                return;
            }

            try {
                CryptoObjectHelper helper = new CryptoObjectHelper();
                signal = new CancellationSignal();
                /**
                 *FingerprintManager.authenticate(CryptoObject crypto, 
                 * CancellationSignal cancel, 
                 * int flags, AuthenticationCallback callback,
                 * Handler handler) parameter explanation
                 * 1. crypto this It is an object of encryption class, and the fingerprint scanner will use this object to determine the validity of the authentication result.
                 * This object can be null, but in this case, it means that the app unconditionally trusts the result of the authentication,
                 * Although theoretically this process may be attacked and data can be tampered with,
                 * This is a risk that the app must take in this case . Therefore, it is recommended not to set this parameter to null.
                 * The instantiation of this class is a bit cumbersome, mainly implemented using the security interface of javax
                 * CryptoObjectHelper can be directly referenced by the written tool class
                 * 2.cancel This is an object of the CancellationSignal class,
                 * This object is used to cancel the current scanning operation when the fingerprint reader scans the user's fingerprint,
                 * If not canceled , then the fingerprint scanner will scan until the timeout (usually 30s, depending on the specific manufacturer's implementation),
                 * this will consume more power. It is recommended that this parameter not be set to null. 
                 * 3.flags flag bit, according to the document description above, this bit should be 0 temporarily, and this flag bit should be reserved for future use.
                 * 4.callback This is an object of FingerprintManager.AuthenticationCallback class,
                 * This is the most important parameter in this interface except the first parameter.
                 * When the system completes the fingerprint authentication process (failure or success),
                 * it will call back the interface in this object to notify the app of the result of the authentication. This parameter cannot be NULL
                 * 5.handler This is an object of the Handler class. If this parameter is not null,
                 * FingerprintManager will use the looper in this handler to process messages from the fingerprint recognition hardware.
                 * Generally speaking, this parameter is not required for development, and can be set to null directly,
                 * because FingerprintManager will use the app's main looper to process it by default.
                 * 
                 * */
                manager.authenticate(helper.buildCryptoObject(), signal, 0, new MyAuthCallback(FingerprintActivity.this), null);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;

        default:
            break;
        }

    }
    @SuppressLint("NewApi")
    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        signal.cancel();
    }


}
 

MyAuthCallback class

 

public class MyAuthCallback extends AuthenticationCallback{

    private Context context;
    public MyAuthCallback(Context context){
        this.context = context;
    }

    /**
     * This interface will be called back after successful authentication. We can prompt the user to authenticate successfully in this method.
     * It needs to be explained here that if our CryptoObject is not null when we call authenticate above,
     * then we can get the Cypher object through AuthenticationResult in this method and then call its doFinal method.
     * The doFinal method will check whether the result will be intercepted or tampered with, and if so will throw an exception.
     * When we find these exceptions, we should treat the authentication as a failure. It is recommended that everyone do this for security. 
     * 
     * */
    @Override
    public void onAuthenticationSucceeded(AuthenticationResult result) {
        // TODO Auto-generated method stub
        super.onAuthenticationSucceeded(result);
        Toast.makeText(context, "success", Toast.LENGTH_LONG).show();
        // AuthenticationResult to get the Cypher object and call its doFinal method.
        //The doFinal method will check whether the result will be intercepted or tampered with, and if so will throw an exception.
        //When we find these exceptions, we should treat the authentication as a failure. It is recommended that everyone do this for safety. 
        try {
            byte[] by =result.getCryptoObject().getCipher().doFinal();
            String date = new String(by, "UTF-8");

            Log.e("TAG", date);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 
     * This interface will call back only when the system fingerprint authentication fails. Note that the authentication failure here is not the same as the authentication error above,
     * although the result is not authentication. Authentication failure means that all information is collected completely and there is no abnormality,
     * but the fingerprint does not match the previously registered fingerprint; but authentication error means that there is an error in the process of collection or authentication,
     * such as fingerprint sensor Abnormal work, etc. That is to say, authentication failure is an expected normal situation, while authentication error is an unpredictable abnormal situation. 
     * 
     * */
    @Override
    public void onAuthenticationFailed() {
        // TODO Auto-generated method stub
        super.onAuthenticationFailed();
        Toast.makeText(context, "Authentication failed", Toast.LENGTH_LONG).show();
    }
    /**
     * The above authentication failure is an abnormal situation in the authentication process. We say that the situation is because of an unrecoverable error.
     * And our OnAuthenticationHelp method here is only called when there is an exception that can be replied.
     * What is a recoverable exception? A common example is:
     * The finger is moving too fast, when we put the finger on the sensor, if we remove the finger quickly,
     * then the fingerprint sensor may only collect part of the information, so the authentication will fail .
     * But this bug is recoverable, so just prompt the user to press the fingerprint again and don't remove it too quickly.
     * 
     * */
    @Override
    public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
        // TODO Auto-generated method stub
        super.onAuthenticationHelp(helpCode, helpString);
        Toast.makeText(context, "Press the fingerprint again", Toast.LENGTH_LONG ).show();
    }
    /**
     * This interface will only be called when an unrecoverable error occurs in the system fingerprint authentication, and the parameter errorCode gives the error code.
     * identifies the cause of the error. All the app can do at this point is to prompt the user to try again. 
     * 
     * **/
    @Override
    public void onAuthenticationError(int errorCode, CharSequence errString) {
        // TODO Auto-generated method stub
        super.onAuthenticationError(errorCode, errString);
        Toast.makeText(context, "Authentication exception", Toast.LENGTH_LONG) .show();
    }

}
 

 

 

/**
 * Reference link: http://blog.csdn.net/baniel01/article/details/51991764
 * 
 * **/

 

public class CryptoObjectHelper {
    // This can be key name you want. Should be unique for the app.
    static final String KEY_NAME = "com.createchance.android.sample.fingerprint_authentication_key";

    // We always use this keystore on Android.
    static final String KEYSTORE_NAME = "AndroidKeyStore";

    // Should be no need to change these values.
    static final String KEY_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES;
    static final String BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC;
    static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7;
    static final String TRANSFORMATION = KEY_ALGORITHM + "/" +
            BLOCK_MODE + "/" +
            ENCRYPTION_PADDING;
    final KeyStore _keystore;

    public CryptoObjectHelper() throws Exception
    {
        _keystore = KeyStore.getInstance(KEYSTORE_NAME);
        _keystore.load(null);
    }

    //FingerprintManagerCompat.CryptoObject buildCryptoObject() 
    public FingerprintManager.CryptoObject buildCryptoObject() throws Exception{
        Cipher cipher = createCipher(true);
        return new FingerprintManager.CryptoObject(cipher);
    }

    Cipher createCipher(boolean retry) throws Exception{
        Key key = GetKey();
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        try
        {
            cipher.init(Cipher.ENCRYPT_MODE | Cipher.DECRYPT_MODE, key);
        } catch(KeyPermanentlyInvalidatedException e)
        {
            _keystore.deleteEntry(KEY_NAME);
            if(retry)
            {
                createCipher(false);
            } else
            {
                throw new Exception("Could not create the cipher for fingerprint authentication.", e);
            }
        }
        return cipher;
    }

    Key GetKey() throws Exception
    {
        Key secretKey;
        if(!_keystore.isKeyEntry(KEY_NAME))
        {
            CreateKey();
        }

        secretKey = _keystore.getKey(KEY_NAME, null);
        return secretKey;
    }

    void CreateKey() throws Exception
    {
        KeyGenerator keyGen = KeyGenerator.getInstance(KEY_ALGORITHM, KEYSTORE_NAME);
        KeyGenParameterSpec keyGenSpec =
                new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(BLOCK_MODE)
        .setEncryptionPaddings(ENCRYPTION_PADDING)
        .setUserAuthenticationRequired(true)
        .build();
        keyGen.init(keyGenSpec);
        keyGen.generateKey();
    }
}

 

 

Address: https://git.oschina.net/qswwers/Android-Fingerprint.git

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325452323&siteId=291194637