In desktop Java there exists a sun.security.mscapi.SunMSCAPI cryptoprovider that we can use with KeyStore to access Windows system certificates stores.
I know that there are similar stores on Android, but I can't find a way to manage these stores (list, add, delete certificates).
What I found is:
1) use KeyChain, but this requires additional interaction with user via Activities;
2) use KeyStore like on desktop and load storage files directly, but a path to these files isn't constant on all devices.
Are are any other approaches that I'm not aware of?
KeyChain is a relatively new addition. Its only available from API 14 (Ice Cream Sandwich) and higher. Nicolay Elenkov has a good blog entry on it at Using the ICS KeyChain API.
KeyStore is an even newer addition. Its only available on API 18 (Jelly Bean MR2) and higher. Nicolay Elenkov has a another good blog entry on it at Credential storage enhancements in Android 4.3.
You might also be interested in Unifying Key Store Access in ICS from the Android Developer's Blog. It tells us the KeyStore has been around since API 4 (Donut), but only the system could use it and it was only used for VPN secrets (Wifi was added later).
The user certificate store was kind of broken until recently. To remove a certificate from the store, you had to delete the entire store (even the certificates and private keys you wanted to keep). See User key/cert management in ICS.
The system's certificate store used to be stored in ROM. That changed after the Diginotar failure because Android had to build new images to remove the compromised Diginotar root. Given that so many carriers don't support their devices, there's literally millions (perhaps billions) of defective devices still out there.
If you want something that appeals to the largest selection of Android devices, then you probably need to use your own store. Perhaps a Java Keystore or SQLciper would be a good choice. Just be sure the database is encrypted with a key that derives from something the user inputs (like a secret). Combine the user's secret with a random value stored on the file system in your sandbox or KeyStore for maximum effect.
If you don't take the user's input, then you hit the "Unattended Key Storage" problem. And that's a problem without a solution. See, for example, Peter Guttman's Engineering Security.
Related
My question is that there is a section in the gradle file called signingConfigs.
Is it a problem if the password is entered here?
Should I be worried about this?
Thanks.
We should NOT do this. These params are there for testing convenience.
We should NEVER store ANY crucial, personal, sensitive information as plaintext.
The testing key passwords and stuff just use dummy values. The actual release key we generate via AndroidStudio or Java keystore directly.
For PlayStore app releases, key files I usually let Google assign, manage and maintain via Developer Dashboard.
This is my first time working on a solo Java project that would generate income from direct sales (meaning I would sell the product instead of a third-party platform).
I was curious as to the following: How can a developer prevent a customer to simply distribute his/her software?
I realize that there are always ways to bypass any sort of security that a developer can put into their project. However, seeing that my product will be run locally (.exe or jar file) there is no way for me to monitor what my client is doing after I sell the product.
Is there a way to put some sort of "illusionary wall" that someone without more advanced knowledge cannot bypass?
Any tips, suggestion or references are greatly appreciated.
I have a server. Some actions within some of my apps will call to the server with some status info. So I know who uses my software. This is plainly stated in the contracts, so no secret stuff.
If I want to limit my software, I do the following:
when my app starts, it collects some system infos and hashes/CRCs them
if there's a matching file, whose contents match the system infos hash, I unlock the app
if there's no such file, or the hash inside it does not match (different system, manipulated, etc) I will (re-)register
registering is either done
by showing the client the hash, forcing him to call/email me, or
the app connects to my server, checks registration infos, shows the page, and then forces user to pay, or unlocks, depending on some other infos i gathered.
on the server side (or manually) I create a key matching the system info hash key
that key gets back into the app (internet or typed manually) and the app checks if that new code matches its system info hash
if keys match, write key to file, and unlock the app
2 downsides:
java is really easy to reverse-engineer:
someone could create a hash generator and create the missing/wrong system info hash file
if you connect through the internet, you should use SSL/TLS, because in other cases, someone could just reverse-engineer (telnet) the answer the app needs to unlock
a good method to prevent reversen-engineering or to make it a lot lot harder is to create pure .exe/elf files. GraalVM native-image is one of those tools that can accomplish such feats. (only using an exe wrapper is rather pointless when it comes to code security, but i good for users)
whenever the client changes things in his hardware, he has to register/reconnect again
All the software i bought for my pc has to be registered once with a license key via internet or has a usb licenser. So maybe this are some ideas something for you. The disadvantages, running a server for product registration or sending an usb-licenser to the costumer. But i'm interested if there are any other solutions
I'm working on an Android app (minimum Android version is 5.0 - API Level 21) that stores data in a local database via RoomDatabase. However, the data needs to be encrypted for which I used SQL Cipher. My question is what is the safest way to store the key used for SQL Cipher. So far, I have two options and a major 'concern' for both of them:
Using the Android Keystore - however my biggest concern here is whether a user with root privileges can access the Keystore?
Using NDK to create a key - from what I've seen the file can easily be decompiled and the key can be extracted somewhat easily.
The app itself is simple so asking the user for a pin/password would not be a way to solve this. The same applies for getting a key from a server since the app doesn't require constant Internet access.
Using Firebase may be the answer because:
It does not need constant network access it will cache the data.
The saved key is not in your app, it is in the web or inside the cache of Firebase service.
It is simple to setup.
You can use one of these products to save your key at Firebase:
Cloud Firestore, Cloud Functions or Cloud Storage.
Or you may use Firebase Authentication instead of saving key.
I've developed an app who run on 100 devices. Want to update it but if I install the new APK give me error. "Android App Not Install. An existing package by the same name with a conflicting signature is already installed".
I researched and found the problem.
I changed my SSD and that's why my debug.keystore file is gone at formatting.
I have found the RSA file in APK. Can I change my new debug.keystore with the value in the old APK?
I researched keytool. Can i use importcert and give two certificate in one debug.keystore?
It that will be possible, everyone can unpack APK and get your private key. Next time do backups before formatting!
I think Google explain it in documentation pretty well
https://developer.android.com/studio/publish/app-signing.html#secure-key
Maintaining the security of your private key is of critical
importance, both to you and to the user. If you allow someone to use
your key, or if you leave your keystore and passwords in an unsecured
location such that a third-party could find and use them, your
authoring identity and the trust of the user are compromised.
If a third party should manage to take your key without your knowledge
or permission, that person could sign and distribute apps that
maliciously replace your authentic apps or corrupt them. Such a person
could also sign and distribute apps under your identity that attack
other apps or the system itself, or corrupt or steal user data.
Your private key is required for signing all future versions of your
app. If you lose or misplace your key, you will not be able to publish
updates to your existing app. You cannot regenerate a previously
generated key.
Your reputation as a developer entity depends on your securing your
private key properly, at all times, until the key is expired. Here are
some tips for keeping your key secure:
Select strong passwords for the keystore and key.
Do not give or lend anyone your private key, and do not let unauthorized persons know your keystore and key passwords.
Keep the keystore file containing your private key in a safe, secure place.
In general, if you follow common-sense precautions when generating,
using, and storing your key, it will remain secure.
MD5, SHA1, SHA256 - different digests ( result of hash-function ) and cannot be used to restore your keystore.
The app I am working on gets all the files from the sdcard but these files are really important and the app should maintain a security issue .So is there a way that the folder or directory that contains the file may be encrypted or locked with a key and only be used by my app?
Please help I am newbie and stuck at this point.
On Android, anything stored on the SD card is not protected by permissions and can be accessed by any application that has permission to touch the SD card (and by anything/anyone that can pull the card out and read it elsewhere). Basically, you need to assume that if you put resources there, they can be accessed by anyone. So, you are correct, you want to encrypt these resources so that even with that access, no one can access them.
Android includes plenty of support for well-known cryptography. In this case, you'll want to use symmetric encryption. The current best practice here is to use AES with 256-bit keys, all of which are natively supported in the Android class libraries. There are plenty of resources on how to do this in the developer documentation online and there is a complete rundown of all the issues you need to think about, and code examples of the entire process, in Application Security for the Android Platform (disclaimer: I'm the author of this book).
You do need a key to encrypt this data, and you need to keep that key secret (anyone that knows it can decrypt the data). You have two options...(1) ask the user for a password every time they use the application and then derive the key from that password, or (2) store the password in your application. (2) is dangerous as Android applications can be readily reverse engineered, where an attacker can simply look into your application and find the key. (1) is preferred as then there is no key stored for an attacker to recover...the tradeoff is that your users need to type in a password to use your application. What you should do here is a function of the risk analysis...how important is this data? Do you need it protected in a strong manner, or are you protecting it to just make things harder for an attacker? Only you can answer that, based on your use cases and the sensitivity/risk of your data.
Have a look at those resources:
http://source.android.com/tech/encryption/android_crypto_implementation.html
http://developer.android.com/reference/javax/crypto/package-summary.html
You should be aware that of course you shouldn't store the key to the encrypted data in cleartext but rather encrypt that itself with a password a user can choose or similar.
This is how to make a new folder:
String SaveFolder = "/Save";
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File mySaveFolder = new File(extStorageDirectory + SaveFolder);
mySaveFolder.mkdir();
Got this code in the public void onCreate
Now it makes a folder with the name "Save".
Edit:
I looked there is not a way to set a password or something.
Though I read here http://developer.android.com/guide/topics/data/data-storage.html#filesInternal it is possible to save files in the internal memory, where users can't get acces too, but I never used that, so I can't help you with that.