I am working on a Java RCP application. A user needs to authenticate himself with his SmartCard to get access to the application. Inside this, he can open/save files which need to be stored encrypted.
Currently, I'm using a password-based AES encryption with a hard-coded password.
This is obviously not secure, so I need a different approach to encrypt/decrypt files.
What arouses this problem is that there are a few requirements to be met:
no guaranteed network connection (must be usable in offline-mode)
multiple users must have access to the files (so no public/private key encryption)
there should not be one "master"-key used for all files
Edit:
I doesn't need to have a very high level of security. It should just be a little bit harder for an attacker to get the key as to just open the distributed JAR file and get the key in plain text.
Any hints would be appreciated.
For each file, create a new key. Encrypt the file with that key (using AES).
Then, for each user that is allowed to read the file, encrypt the new key with their public key (one that corresponds to a private key on their smart card). Store these encrypted keys with the file.
When a user wants to read a file, the software uses his smart card to recover the content encryption key used for the file.
The file format could use PKCS #7's Cryptographic Message Syntax or OpenPGP.
Caveat: I am not well-versed in security and this is just something that crossed my mind.
As a suggestion, make the password for each file be a hash containing a known salt that is randomly generated for each file, and a single passphrase that is encrypted individually for each user. You can safely store the random salts locally, because these are not the key to the file, and no user knows the passphrase to unlock the file. By encrypting and signing the passphrase with public key encryption, you can authenticate users and control access on a per-user, per-file basis.
This way, you could use public key encryption from each user to deliver the passphrase, which is not stored anywhere in the system, secure the files independently of each other of each other, and not be dependent on outside sources.
Related
I am trying to develop an android app in java which needs encryption. Also I want to use AES-256 for encryption. But when I look a tutorial of it, It always generates a random key. My question is: How can I decrypt a string if I encrypt it with a random key? Also I tried almost every code in web, but none of them worked, so can you provide a AES-256 encryption code with no salt and IV. If I know something wrong, please correct me and teach me the truth.
Details: I am trying to make a password manager app. App has two passwords, first one is the master password that we use for encryption string data. Second one is the passwords that we want to manage. Master password is stored in users mind. And other password will be stored in the app with encrypted version. When user wants to see his passwords he will input his master key to decrypt the encrypted passwords. So how can I do it? And user's master password will be 32 or 64 digit and I don't think we need to generate a random key. Can you show me some way? I am not native english speaker, sorry for my bad english. Thanks for help.
My question is: How can I decrypt a string if I encrypt it with a random key?
You can't. You need to save the key (somewhere). Then when you want to decrypt the file you restore the key that you used to encrypt the file and use it to decrypt.
Here is an Answer that explains how to save an AES key to a file and restore it: https://stackoverflow.com/a/7176483/139985. Notice that the example encodes the key in hexadecimal before writing it to disk.
However. Anything that entails storing an encryption key (in the clear) in a file in the file system is vulnerable. If someone or something can compromise the security of the OS / file system where the key is held, they can read the file containing the key ... and ... decrypt what ever the key has been used to protect.
A better idea is to use some kind of secure key store / vault.
My advice: if you are write an app that manages passwords for other people, you really, really need to have a deep understanding of how to do this securely. And if you don't, pay a qualified IT security professional to design and implement that aspect of your system for you.
Just reading some tutorial and asking on StackOverflow does not cut it!
I want to use Aes to encrypt some data and decrypt them later. I created a jks keystore, the problem is where to read the keystore and keys password. Putting the master password in the code seems not really secure. Same thing if I put in the properties file or environment variable. I could use jasypt library to keep encrypted the master password in the properties but again I need another password and the problem again where to store it. What is the best way or guidelines in these cases? I can't use a command line input neither a command line parameter.
Another question: if I keep my keys into the Google memcache, is it secure?
Check Vault project.
I don't recommend you to use Google Memcache for such things. It's pretty similar to situation, when you store your master key in database or file. However, you decide, what level of security for data you need. Sometimes, properties file is enough.
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.
When you compile a .java file into a .class file, if you had a line like
String s = "This is a String"
If you open up the .class file in a text editor, you will see
This is a String
Somewhere in the file amidst the gobblety gook.
Which is fine and dandy for most stuff, but not when dealing with sensitive information like API keys.
Of course, one alternative is to read the API key in from another file, but that just makes it EASIER to find the key, as now the person can just open "key.txt" when they open the .jar file.
So how do you encrypt a string literal in your .class file?
When you send code to a 3rd party, you loose all control over it. Even if you where to embed the API key as an encrypted string, an attacker could still try, and potentially succeed in breaking it, which would make all your encryption/decryption efforts in vain.
The best solution, in my opinion, would be to not provide any sensitive information within the application, but rather provide it with an ID of some sort. Any sensitive values which it needs would be then pulled through the use of a secure connection.
If you use a key to access a 3rd party API there is no way to protect that key from the end-user IF you ship it with your code / application or you want your application to be able to access the 3rd party API without a middleman.
The end-user could just read all data send from your app to the end-point and know the API key. Regardless of any measures you took to encrypt it you will need to send it atleast once decrypted to the 3rd party.
The safe way to do this is to require your user to log in to a service provided by you, send a request to YOUR service and then YOUR service (which is presumably not located on the machine of your end-user) sends a request to the API with the key. So the end-user never knows of the key.
If you store the information in the class file, the decryption key should come from outside of the class. You can crypt the data, but if you have all the information within the class file, you are lost.
You should store API keys in config files. You have a different API keys for development and for the live, right?
Other possible solution is to use KeyStore, which allows you to store sensitive information in publicly accessible format. Only the holder of the secret key can decrypt the sensitive data.
Even if you keep that information encrypted in your class, a hacker can find the mechanism to decrypt that from your code only. So IMHO it's better to keep that encrypted information in some other file, and read that file. Also, restrict the access to that file using OS security mechanisms.
How exactly SQLCipher for Android Application works?
http://sqlcipher.net/design/
As i understood it all depends on PRAGMA key and this key should be saved on app, maybe in binary.
However this is insecure as alomst everyone could decompile .apk file on rooted phone.
Maybe i missed something ?
Thank you.
As i understood it all depends on PRAGMA key and this key should be saved on app, maybe in binary.
No.
Maybe i missed something ?
The key comes from the user, in the form of a passphrase that the user types in. In SQLCipher for Android, this passphrase is passed to methods like getReadableDatabase() on the revised version of SQLiteOpenHelper.
Yes, securing the key is the tricky part. Ideally it's (partly) supplied by a password the user enters when signing on to the app, but that isn't always ideal, so sometimes you have to resort to the much-maligned "security by obscurity" approach and assemble the key from bits and pieces stashed here and there.
The SQLCipher team universally recommends against embedding a fixed key in an application binary. No matter how creative an application is about obscuring an embedded key, a sufficiently determined attacker will be able to extract it from the application package and open a database.
Unfortunately some applications still choose to use SQLCipher with embedded keys as a rudimentary form of DRM, i.e. by making it difficult for casual users to view data. However, this does not provide any substantial amount of security.
If you need to protect sensitive data the best approach is to use a key derived from a strong passphrase entered by the user. SQLCipher provides strong key derivation automatically, so all you need to do is provide the user passphrase through PRAGMA key or one of the equivalent keying mechanisms provided in SQLCipher wrapper libraries.
I generate key form secureRandom and then save key on KeyStore (BKS).
For KeyStore i generate password using: random, user info, device info and password.