Closed mezpahlan closed 4 years ago
Hi,
thanks for the detailed question.
Regarding step 4, why do you need to encrypt received secret? As much as I understand in the asymmetric cryptography, you should already receive the secret that is encrypted with server's public key.
And if it's not 😉? It's also my assumption that everything in Shared Preferences is potentially hackable so you wouldn't want to put anything sensitive there without some form of protection.
If this secret allows elevated privileges without further checks then it needs to be secured on disk, right?
It's possible that I've got this whole authentication thing misunderstood, but I thought I would ask just in case.
I looked how Whorlwind works and it is possible to have the same behavior as them.
You need to implement custom CryptoFactory
.
CryptoFactory should create and initialize Cipher with RSA algorithm and use either public key for encryption or private key for decryption operation. Keep in mind you should store public key like they do here.
Crypto should work out of the box in this case as it will use CryptoObject
created by your CryptoFactory
.
And if it's not 😉? It's also my assumption that everything in Shared Preferences is potentially hackable so you wouldn't want to out anything sensitive there without some form of protection.
If this secret allows elevated privileges without further checks then it needs to be secured on disk, right?
It's possible that I've got this whole authentication thing misunderstood, but I thought I would ask just in case.
IMO this is not Goldfinger's scope. In this case you should create unlocked Cipher using server's public key and encrypt your data before you save it in SharedPrefs.
What Goldfinger tries to achieve is that it takes locked CryptoObject, handles user authentication and then helps with encrypting/decrypting data using the now unlocked CryptoObject.
Seems like in your case you don't need Fingerprint authentication but standard cipher which you want to use to encrypt data received by the API if I understood correctly.
Yes I think I agree too. Can I just confirm my understanding so far if you don't mind?
CryptoObject
and use that to encrypt and write data independent of Goldfinger.CrytpoObject
to facilitate this.flatMap
these operations relatively simply.I think that's the best I can get for my use case until I change my use case.
What I was trying to do over the weekend was create a custom CryptoObjectFactory
to create the asymmetric CryptoObject
and use that for read / write operations. I could do this with the exception of my own requirement of not having to reauthenticate to write.
My problem was that I have to create either a BiometricPrompt.CryptoObject
or return null
here. Returning a BiometricPrompt.CryptoObject
for my write operation will tell Goldfinger to initiate the prompt to unlock the CryptoObject
(which is perfectly fine, just not what I want). And returning null
throws an error from the same function.
I was hoping something like this could be implemented using a new Params
and a separate branch of the if statement here. Maybe something like this:
@Override
void onCryptoObjectCreated(@Nullable BiometricPrompt.CryptoObject cryptoObject) {
creatingCryptoObject = false;
if (cryptoObject != null) {
startNativeFingerprintAuthentication(params, callback, cryptoObject);
} else (if params.useAsymmetricWrite()) {
log("Using public key for encryption");
// Do something here
} else {
log("Failed to create CryptoObject");
callback.onError(new CryptoObjectInitException());
}
}
As you quite rightly say, this isn't the scope of Goldfinger.
Standard asymmetric cryptography uses your public key when you want to encrypt message sent to the server, and private key when you want to decrypt the message received by the server.
In that flow, when user registers using the password, you want to encrypt his password using your public key and send it to the server.
To do that you need to initialize your Cryptography like this. See how they fetch publicKey, initialize Cipher with publickey and Goldfinger
will automatically use that Cipher to encrypt the value which you can use.
Afterwards, when you receive new value from the server (it should be encrypted) you should store it into shared prefs.
When user wants to login again, you want to authenticate the user by decrypting the saved value. Here you need to initialize Cipher like this.
You load existing key which is your private key, initialize cipher, and with that you can decrypt the value. When user authenticates himself you will get decrypted value which you can use.
As much as I can understand that is exactly what Whorlwind does.
As much as I can see what you need is to do some encyption/decryption outside of Goldfinger flow.
In that case, separate Cipher initialization in some sort of Cipher Factory and reuse the factory for Goldfinger initialization and for encryption/decryption outside of Goldfinger flow. Here you can see how to use existing cipher to do encryption or decryption operation.
TL;DR: 1) Encrypt password with Goldfinger, send to server 2) Encrypt server response if it is not encrypted using same cipher but without Goldfinger 3) User wants to login, decrypt server secret with Goldfinger from prefs 4) Do whatever is needed with now decrypted secret
This is out of scope so I am closing this issue. Hope I managed to help and clear some things out.
Thanks again, you have. Again, really nice library.
Hi there, I really like this library and the API is really nice but I'm struggling to understand how I can do the following. The use case is that I want to be able encrypt data without showing the BiometricPrompt but only decrypt after the user has successfully authenticated via the BiometricPrompt.
I believe this is known as Asymmetric crypto (although I may have confused the terms, forgive me). There is a rather outdated sample in the Google Android Samples for this that uses a
KeyPairGenerator
which is what I want to do but I also want to be able to use your library.I notice that your
CryptoObjectFactory.Default
implementation assumes Symmetric crypto and also that the library in general assumes that for all encrypt / decrypt operations we would show a BiometricPrompt. So I'm finding it a little difficult customise the factory for my needs.Here's a fuller usecase:
What I can't do at the moment (or at least I don't know how to achieve) with your library is step 4 because I need to ask the user to reauthenticate.
Incidently this is how Whorlwind works but the docs are super confusing, they don't supply easy integration to the new BiometricPrompt and your library seems better maintained.
Is this possible / desirable?