3

I need an end to encrypt different strings and related decryptions after user authenticate using fingerprint scanner.

Following this project (https://github.com/StylingAndroid/UserIdentity/tree/Part1) and changed "tryEncrypt" method like below:

  private boolean tryEncrypt(Cipher cipher) {
    try {
        cipher.doFinal(SECRET_BYTES);
        String one = "augusto";
        String two = "test@gmail.com";
        String three = "3333333331";
        byte[] oneEnc = cipher.doFinal(one.getBytes());
        byte[] twoEnc = cipher.doFinal(one.getBytes());
        byte[] threeEnc = cipher.doFinal(one.getBytes());
        Log.d("test", "oneEnc: " + Base64.encodeToString(oneEnc,0));
        Log.d("test", "twoEnc: " + Base64.encodeToString(twoEnc,0));
        Log.d("test", "threeEnc: " + Base64.encodeToString(threeEnc,0));

    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

I'm getting this error:

java.lang.IllegalStateException: IV has already been used. Reusing IV in encryption mode violates security best practices.

What is the correct way on how to do it?

Thanks

*******************UPDATE:*****************************

To help others to get solve this problem I used this library and worked like charm:

https://github.com/Mauin/RxFingerprint

Augusto Picciani
  • 788
  • 2
  • 11
  • 31
  • Did you get any further with this? Did you try `init()` prior to `doFinal()`? And did you then get the same *android.security.KeyStoreException: Key user not authenticated* like me? How do you use the Cipher multiple times? – Stephan Henningsen Aug 24 '16 at 12:05
  • I tried the RxFingerprint sample app, and it too seems to require authentication every time the app wants to do an encryption or decryption. I guess this makes sense. – Stephan Henningsen Aug 26 '16 at 09:45

2 Answers2

4

You have a problem because your are using a single instance of the Cipher for multiple encryptions (dofinal). You are using a single vector initialization (IV).

Take a look on an option of how to initialize a cipher.

SecureRandom r = new SecureRandom();
byte[] ivBytes = new byte[16];
r.nextBytes(ivBytes);

cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivBytes));

As you can see, you need to specify the initialization vector. The initialization vector can not be repeated to guarantee that the encryption works.

In your scenario, you probably gonna need to perform a new initialization.

*Ps: It's also possible to use the Cipher initialization without the IvParameterSpec. In this scenario, the class will generate one for you. However, I believe that you need to perform a initialization per DoFinal to guarantee some randomness.

Oximer
  • 548
  • 5
  • 19
  • I get *android.security.KeyStoreException: Key user not authenticated* if I `init()` and then `doFinal()` as if the Cipher can only be used once for either encryption or decryption. Is this really true? Is the Cipher returned from `FingerprintManager.AuthenticationCallback.onAuthenticationSucceeded()` really supposed to only be used maximum once to perform a the `tryEncrypt()` mentioned in OP? – Stephan Henningsen Aug 24 '16 at 12:03
  • @StephanHenningsen: You can use `setUserAuthenticationValidityDurationSeconds` when generating the key. – Michael Aug 24 '16 at 13:11
  • 1
    So is it correct that the Cipher (or SecretKey I suppose it is?) will only work once after authentication? Will `setUserAuthenticationValidityDurationSeconds` allow me to use it more than once? I'd really like these questions answered so I can fill in the missing pieces and try understand what's going on here =) – Stephan Henningsen Aug 24 '16 at 13:16
  • 1
    Have you tested this with success? I can't make it work; using `setUserAuthenticationValidityDurationSeconds(600)` in combination with `setUserAuthenticationRequired(true)` still only allows me to use the Cipher/Key once. – Stephan Henningsen Aug 26 '16 at 07:47
  • I need one favor, How to reproduce the crash? – Happy Nov 23 '16 at 06:27
0

To help others to get solve this problem I used this library that worked like charm:

https://github.com/Mauin/RxFingerprint

Augusto Picciani
  • 788
  • 2
  • 11
  • 31
  • 5
    Can you explain how this helped you use the same authentication to encrypt/decrypt more than once? – Oded Niv Jul 21 '18 at 06:47
  • 3
    This does not answer the original question about using the same instance of the cipher to encrypt multiple values. – Max Ch Apr 05 '19 at 13:29