We have apps developed for both Android and iOS which interacts with devices via BLE and uses a Spring boot backend server in which they have registered and logged in. They can log in with the same account on either Android or iOS (obviously). During the interaction we can get codes that the user may need in the future. To handle that we currently do this:
Android: Encourage the user to write the code down. Use the users login information (username/password) to generate a symmetric key which is used to encrypt data which is then sent to and stored in our server. That way, only the user can retrieve it and decrypt it. Drawbacks would be the way we generate the key in itself and the obvious fact that a user that has forgotten password/changed password cannot decrypt the data anymore.
iOS: Encourage the user to write the code down. Then store it in KeyChain with the kSecAttrSynchronizable attribute so it can sync to iCloud KeyChain. That way the user should be able to get it on any other iOS device. Obvious drawback is that if the user chooses to switch to Android then the code cannot be retrieved there.
Is there anyway we can store sensitive user app data for both platforms? We could store it in our server but since we want the users to encrypt it themselves (so we can't see the content of the data) we need some unified way. There is no magic Spring boot feature to store "encrypted user data" for a specific user which only that user can retreive?
Have thought about using Google Drive and store it in the hidden app folder. But I'm guessing that wont work with an iOS app that uses the Google Drive SDK?
EDIT
Just to exemplify:
A user buys the device and connects it to its Android app. The user then changes the reset code of the device which is what would be needed if the device was ever "factory reset" (of course not factory, but cleared). When that is done we encourage the user to write this code down/remember it. Then lets say the the user loses the Android phone and buys an iPhone. He logs in to the exact same account but now might need to reset the device in order to start using it again. If that code could have been stored somehow using the account (or using the users google account or anything) then he wouldn't have to remember it.
Related
I have an app, that on the first start generates a random user id and password to set up an account on my server and store them in the shared preferences.
I am looking for a way to write this data into the cloud so that if the user installs the app on a second device it will retrieve this account data and use them on the second device as well.
On iOS, this is a trivial task but I am still trying to figure out how to achieve this on Android. I tried an approach with Firestore, but it seems to be able to write to the Firebase database, the user has to log in with Firebase. I assumed being logged in to a Google Account on the device would do this, but I still get invalid permissions back when writing data.
I do not want to force the user to a separate login.
Any ideas on how to approach this task? Is it possible on Android at all?
I have an app, that on first start generates a random user ID and password to set up an account on my server and store them in the shared preferences.
If you have your own server where you authenticate the users, and you also want to authenticate to Firebase, then I recommend you check:
Custom Authentication System
I am looking for a way to write this data into the cloud so that if the user installs the app on a second device it will retrieve this account data and use them on the second device as well.
You just should never simply store the credentials in Firestore. Storing passwords in cleartext is one of the worst security risks you can inflict on your users. You should either use authentication with your custom system or use one of the existing providers, like Google, Facebook, etc.
I tried an approach with Firestore, but it seems to be able to write to the database, the user has to log in with Firebase.
It's recommended to authenticate the user in Firebase before reading/writing data from/to Firestore because you can secure your database using Firestore Security Rules.
P.S. Don't store data in ShartedPreferences because this type of data is stored locally and doesn't persist application uninstalls.
I wanted to know if when there's an firebase authentification, it's possible to get the source of this authentification?
To know if it's from my iphone app, android app or web app.
Why :
My web app isn't on the web, but on local server. I want to distribute this web app with server (It's for a personnal project but it could have 10 prototypes). So everybody can get my firebase config. And I don't want that someone can create account from the web firebase api because I accept google/apple and email/password auth. I can't disable email/password for my project purpose.
I hope this is clear.
To be more clear, if the email/password auth is created, is it possible to know if it's from android app or iphone app or webapp?
Thanks
The provided APIs for Firebase Auth don't give any indication which platform was used to create the account. Firebase intends for all accounts to work across all platforms using the provided SDKs and APIs accessible for each platform.
If you want to record your own per-user data in a database, you're free to do that. Note that this is not really "secure" in that each user could effectively manipulate your database or APIs to indicate whatever they want about their platform. If you do not have this sort of security in mind, then you can simply trust your own code to write, and late read, the user's platform in a database after they sign up.
To be more clear if the email/password auth is created, is it possible to know if it's from the Android app or iPhone app, or web app?
Yes, it's possible. Let's say we want to know if a user has signed in from Android. When the user creates an account from an Android device, most likely you are storing user data as objects in the database. The simplest solution I can think of is to add another property in your User class, called "platform" and set it to "Android". If the user signs up with an iPhone, then set the property to "iOS". Same thing for the web. Knowing that the user might change the device, every time the user opens the app check that value against the OS the user is using. If the OS is changed, also change the value accordingly. This way you'll always know the OS the user is using. If you allow the users to use multiple platforms, for Android, there is a function called getProviderData():
Returns a List of UserInfo objects that represents the linked identities of the user using different authentication providers that may be linked to their account.
Similar functions can be found for the other platforms as well.
Does anyone knows what is the most secure way to store sensitive information in application? Because using internal storage and shared preferences is vulnerable if person who want that information have a rooted phone.
Case is that I have some kind of activation code which needs to be stored somewhere inside the phone (not on server) for further communication and authentication with server side, that code needs to be secured and not available to other apps and users, even on a rooted phone. Also, user can not be bothered with additional verification (he enters the PIN code when he enters the application and send that code to the server side for authentication) .
Bottom line, is there a secure way to store something and to be secure that it will remain hidden, even on a rooted phone?
Unfortunately the commenters are correct. There is no way to guarantee with 100% security that the activation code can't be hacked. Microsoft has spent millions of dollars on this, and there are still pirated copies of Windows out there, because at the end of the day you have no control of the code on the client. If you endow the client with the ability to decrypt or otherwise access this stored authentication code (without needing to go to the server), then someone can reverse engineer the app to undo your protection. This is true even if you retrieve a decrypt key from the server.
The best way to do this depends on your use case, but here are some ideas:
Have the client submit the "activation code" to the server, where you can blacklist it if you think it's stolen. This is how Windows works. This is the only option you have if you want to use an activation code and not bother the user.
Have the user register an account and have the app resubmit the user's credentials each time it runs. This way you have a user account to deactivate if you suspect piracy.
Have the server provide the decrypt key. This does not guarantee that the activation code stays safe, but it does up the bar for potential reverse engineers.
Drop the whole DRM idea completely, and focus your attention on making a good product. Studies that music companies have shown that dropping the DRM makes no difference in the number of people who buy your product.
I'm developing an Android application that needs to backup (and restore) some data stored in an sqlite database to (from) google (or gmail). But I don't have a clue about where to start. I read the backup guide in the Android documentation. But that's not what I need since the backup operation in that way might not be taken immediately, and it needs the device user to turn on the backup option in "settings->privacy".
I need a way that first authenticates the user's account (already on the device) using OAuth or OAuth 2.0, then after authentication, the app sends the data to gmail and can later get it back from gmail to restore it to the device.
How can I implement this?
Another question: when I send the data to gmail, what format should i use? The database file, XML, or something else?
I'm looking for something like the Keychain on the iPhone, but for Android development. Something that gives me the capability to save small key-value pairs that are persistent and unchanged even if the user reinstalls the application.
Is there something like that? Can I use the standard preferences that way?
I would like to achieve a behavior similar to the way it works with games on a PC - writing the save files to another folder so that after deletion and reinstallation the save files are not lost.
Edit:
The bounty ran out without somebody mentioning the accountManager. I just stumbled over it. Would that be a method to achieve the behaviour described by me?
You you use storage on the SD card like Michael Cramer stated ( Let the user know you are storing data :-) ). The data on the SD card is not deleted when the app is removed.
You could on the other hand use a server which stores all the details which can be downloaded as and when required and instead of using a user name use the IMEI of the phone which is unique. That way even if the user reinstalls the OS he will still be able to refetch the settings.
for getting the IMEI you may refer : How to get the device's IMEI/ESN programmatically in android?
You have the real thing here:
By integrating Smart Lock for Passwords into your Android app, you can
automatically sign users in to your app using the credentials they
have saved. Users can save both username-password credentials and
federated identity provider credentials.
Integrate Smart Lock for Passwords into your app by using the
Credentials API to retrieve saved credentials on sign-in. Use
successfully retrieved credentials to sign the user in, or use the
Credentials API to rapidly on-board new users by partially completing
your app's sign in or sign up form. Prompt users after sign-in or
sign-up to store their credentials for future automatic
authentication.
https://developers.google.com/identity/smartlock-passwords/android/
Since Android & iPhone-like phones will normally run with a data plan, I would suggest that you save your key-value pairs into a centralized server. When the app goes through the uninstall, followed by an install process, just resync it with your server.
Yes. Preferences are persistant and will survive a normal application upgrade.