Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No token returned when using PIN backup #85

Closed
maleriepace opened this issue Jun 15, 2017 · 28 comments
Closed

No token returned when using PIN backup #85

maleriepace opened this issue Jun 15, 2017 · 28 comments

Comments

@maleriepace
Copy link

When I use the backup method, it doesn't seem that the password is encrypted and stored. Do you have an example of how withBackup should be implemented?

@mjwheatley
Copy link
Owner

mjwheatley commented Jun 15, 2017

Currently, it is that way by design. So you are saying you don't care if they authenticated with a fingerprint or the back up credentials, either way you want to encrypt or decrypt a token?
If a user is going to authenticate via backup credentials, shouldn't they just use your login form instead? What is your particular use case? After all the main purpose of this plugin is fingerprint authentication. Perhaps you could display a message that says only fingerprint authentication is accepted if you receive withBackup: true from the plugin.

@maleriepace
Copy link
Author

Thanks for the quick response! I am implementing an option to authenticate with a fingerprint or PIN to give users an easier, faster way to log in instead of typing in their password. I'm hoping to include the PIN option only because not all devices will have a fingerprint reader. I created a fork and have been trying to figure out how to get an authenticated cipher from the backup authentication response but with no success so far.

@mjwheatley
Copy link
Owner

ok, I just started looking into it as well. I think the key is looking at the CryptoObject.
In onAuthenticated when authentication happens via fingerprint, there is a FingerprintManager.AuthenticationResult param available that has the CryptoObject that was set on the Fragment mFragment.setCryptoObject(new FingerprintManager.CryptoObject(mCipher));
So I am going to try creating a new CryptoObject in the same way if authentication occurred using the backup.

@mjwheatley
Copy link
Owner

Yep, that seemed to do the trick.

mjwheatley pushed a commit that referenced this issue Jun 15, 2017
* Fixed issue #85 No token returned when using PIN backup
@maleriepace
Copy link
Author

Wow, thanks!

@maleriepace
Copy link
Author

Actually, I'm still getting an illegalblocksizeexception here when encrypting using a PIN. Are you seeing that?

@mjwheatley
Copy link
Owner

Probably because there are 2 flows to get to the backup credentials.

    • isFingerprintAvailable() // true
      • secret key != null
        • !initCipher()
          • !mDisableBackup
    • isFingerprintAvailable() // false
      • useBackupLockScreen() // true

In both cases the cipher has not been initialized and the secret key could may not have been generated.

Do you know which user flow is initiating the backup credentials activity ( 1 or 2)?

It probably worked for me because I had previously authenticated with a fingerprint and created a secret key and initialized my cipher.

So to make this work properly I will need to insure those both get initialized if not isFingerprintAvailable().

mjwheatley pushed a commit that referenced this issue Jun 16, 2017
* create key and init cipher if only using backup credentials.
@mjwheatley
Copy link
Owner

Please test the commit I just pushed and let me know if that helps with the issue. If so, I will publish the fix.

@mjwheatley mjwheatley reopened this Jun 16, 2017
@maleriepace
Copy link
Author

isFingerprintAvailable() // true
secret key != null
!initCipher()
!mDisableBackup

I've been unable to get getSecretKey to return a null key or initCipher to return false in my testing.

isFingerprintAvailable() // false
useBackupLockScreen() // true

This flow doesn't seem to work at all. I never get the response to hit any breakpoints in onActivityResult found in either FingerprintAuth or FingerprintAuthenticationDialogFragment. Looks like in this scenario, the fragment is never initialized, which explains why the breakpoint isn't hit in that class, but I don't see why I can't get into onActivityResult in FingerprintAuth. After the correct PIN is entered, the PIN screen closes with no response and no messages in the log.

@mjwheatley
Copy link
Owner

Sorry, Those flows may have hard to follow.

Let me try to clarify.
My recent code change will create a secret key no matter what now, so it will error out if it can't generate the key. Then if the isFingerprintAuthAvailable() is false, it will check if the lock screen is secure, useBackupLockscreen() is true. Finally it will call showAuthenticationScreen(). That method starts the user credentials activity with request code REQUEST_CODE_CONFIRM_DEVICE_CREDENTIALS. When that activity finishes you should get a breakpoint to hit in onActivityResult() in FingerprintAuth.java.

@maleriepace
Copy link
Author

Hey, sorry for not getting back to you right away. I've been doing some testing and tinkering on my end. I think I'm going to have to either scrap the PIN idea or figure out a different way to do it. I was originally looking to do something similar to the Mint or other banking apps where you can actually set your own PIN to authenticate with, but I figured the unlocking PIN would be ok instead since that's what your plugin uses.

If I use the plugin on a device with no fingerprint ability, I get a InvalidAlgorithmParameterException when generating the key because there are no fingerprints registered. Thanks for your help! I think I'm just going to use fingerprint only for now.

@walternicholas
Copy link

Thanks mjwheatley for writing this plugin!

Just added it to my app and I'm having the same problem as maleriepace

If I attempt to "USE BACKUP" (device's PIN unlock) to encrypt or decrypt, I get ILLEGAL_BLOCK_SIZE_EXCEPTION

Going to have to set disableBackup = true (not ideal) until we can get this fixed.

Let me know if there is any way to help test.

@mjwheatley
Copy link
Owner

Hi @walternicholas,
What device were you testing on? Was it with or without fingerprint hardware? If with, were there fingerprints registered on the device or not?

@mjwheatley
Copy link
Owner

If you are able to debug, can you provide the line of code that is causing the exception?
Are you seeing the error message printed by the code below in logcat?

catch (IllegalBlockSizeException e) {
            Log.e(TAG, "Failed to encrypt the data with the generated key: "
                    + "IllegalBlockSizeException: " + e.toString());
            errorMessage = PluginError.ILLEGAL_BLOCK_SIZE_EXCEPTION.name();
        }

@walternicholas
Copy link

walternicholas commented Sep 14, 2017 via email

@walternicholas
Copy link

walternicholas commented Sep 14, 2017

@mjwheatley

Yes that is the exact error I'm seeing printed in logcat, coming from the block of code you posted (623-626 in FingerprintAuth.java).

This error when I am trying to decrypt appears, after these 3 steps:

  1. Give the fingerprint scanner a finger which isn't registered.
  2. Tap "USE BACKUP" button which appears after first fail.
  3. Enter the correct 4-digit backup PIN for unlocking the device.

@mjwheatley
Copy link
Owner

So you have to have a failed attempt first for the backup button to appear? Is this device specific or a custom implementation. The backup button is always present when testing on my Nexus 6p.

@mjwheatley
Copy link
Owner

Is the e.toString() printing out any additional information?

@walternicholas
Copy link

Actually no that was my mistake, I didn't notice the USE BACKUP button on my first try. Was editing my comment to fix that when you posted. I still get the same problem, encrypting or decrypting, with or without first providing a wrong fingerprint before hitting USE BACKUP.

@walternicholas
Copy link

walternicholas commented Sep 14, 2017

From logcat:
E/FingerprintAuth: Failed to encrypt the data with the generated key: IllegalBlockSizeException: javax.crypto.IllegalBlockSizeException

@mjwheatley
Copy link
Owner

Can you tell which line in the try block, lines 578 - 618, is triggering the catch?

@mjwheatley
Copy link
Owner

I'm guessing that it may be line 605-606

bytes = cryptoObject.getCipher()
                            .doFinal(Base64.decode(mClientSecret, Base64.NO_WRAP));

Referencing https://developer.android.com/reference/javax/crypto/Cipher.html

Public methods
doFinal

int doFinal (byte[] input, 
                int inputOffset, 
                int inputLen, 
                byte[] output)

Throws IllegalBlockSizeException
if this cipher is a block cipher, no padding has been requested (only in encryption mode), and the total input length of the data processed by this cipher is not a multiple of block size; or if this encryption algorithm is unable to process the input data provided.

@mjwheatley
Copy link
Owner

@walternicholas if possible, perhaps we can arrange a time to investigate this together. Would you be agreeable to that?

@walternicholas
Copy link

@mjwheatley Yeah I'd be happy to help investigate. What time works for you?

@mjwheatley
Copy link
Owner

Contact me at mattjwheatley@gmail.com and we can coordinate.

@mjwheatley
Copy link
Owner

Fixed by setting userAuthRequired to false and regenerating secret key by uninstalling and reinstalling.
Releasing new version 1.4.0
See release notes for changes.

@jenkinssgs
Copy link

Hi,
I need to Re-Design the Authentication window of FingerprintAuth, Is there any way to do. Your Helps would be greatly appreciated. Thanks.

@mjwheatley
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants