Storing AES Key in Android Device Securely - java

I am trying to encrypt a list of strings specified by the user. The AES key used to encrypt and decrypt this data must be saved on the device so it can be used to decrypt the data whenever the user needs to. I have read that using Keystore is a good option for storing keys, but most of the guides I have read about it relate it to signing your application, which is not exactly what I want. My application requires the user to input a password, which then decrypts the String data using the key which is unlocked with the password. How do I do this?
Thanks.

Its hard to answer your question without having you define "securely" in a precise manner. Are you talking about security against other apps? Security against other users? Security against theft of device? Or security against loss?
In addition, what level of security are you talking about? Is the data being encrypted under the given key sensitive enough to warrant serious considerations about how the key can be stored?
To my understanding, if the data is of highly sensitive nature, you should derive the key directly from the password using a password-based key-derivation function such as PBKDF #2, Bcrypt or Scrypt. In this way, the key material needs not be stored on your device directly.
If you intend to store the master encrypting key for whatever reason, encrypt under the password key and store as a Base64 string under SharedPreferences with MODE_PRIVATE to protect it against other apps. Even if the key was recovered by a malicious user/device theft, without the proper password key, the key material itself is useless.
If you wanted to protect the key against loss, you shouldn't store the key on the device but rather on your own server, again encrypted under the password key so that database compromise will not result in data compromise as well.
In all, I'd suggest you try not to store any sort of private key onto the device itself and instead used the password-derived key as your master key for all cryptographic operations. Leave the keystores for private-keys generated in public-key cryptography and known public key certificates.

Related

AES encrypt/decrypt with stored key?

I am currently programming a password manager.
The passwords are stored in a database. But now I want to encrypt the passwords in the database. I don't know anything about encryption, but I came across the AES algorithm.
Encrypting/decrypting in a single class with a string works. However, when I want to transfer this to my PW Manager, a new key is generated each time, which is why I can no longer access the stored passwords. So I think I need to store the key somewhere so I can encrypt and decrypt the passwords over and over again, right?
If I am wrong, please correct me :)
My questions now are:
1. How and where can I store the generated key?
2. Does it even make sense to save the key? Or are there better methods for this?

Best way to password protect a Java console application

I am looking for a best-practice or standard method to password protecting a console application. I have researched various methods and would like some feedback on my approach.
I have decided to hash my password using Argon2 so that I only have to store the one-way hash. Everything is working as expected. The question I have is where do I store the hash? Should it be hard-coded? Should I store it in a separate file and read it in? What is the most secure way to approach this? At the end of the day I am writing this application to learn and would very much like to learn to do it the correct way. Links to any relevant reading material would also be appreciated. I continue to google...
EDIT: So what would the potential drawbacks be if I stored program password as hash in a file. The user would have to know the password to use the application. Then let the program password that is protected by the hash be the encryption key to secure the sensitive information? Even if the source code and/or hash file is manipulated, the sensitive data would not be readable since the correct password is used as the key...what am I missing?
First of all, Argon2 is a fine key derivation function for turning passwords into encryption keys.
However, if you are using the Argon2 hash as an encryption key, then don't store it on disk, obviously. If you store the encryption key next to the encrypted data you might as well not encrypt at all. One could even argue that it's worse, because it gives a false sense of security.
Properly encrypted data is useless without the key, so you don't have to protect the application itself. Just ask for the password if and when you need to encrypt or decrypt something. You can consider keeping the hash in memory for a while so you don't have to ask for it repeatedly, but don't persist it.
This is exactly how GPG works, for instance. It doesn't store any password hashes anywhere. Instead it stores private keys encrypted and just asks for the passphrase if it needs to decrypt a private key.

Is it safe to store the encryption/decryption key into a static variable?

I am developing an app in Android Studio and I am passing data from server to phone via JSONs.
Is there a way for me to encrypt JSON data?
Is it safe to store the encryption/decryption key into a static variable? If not where should i store the keys in Android?
None of theses SO questions below helped me:
Can I encrypt my JSON data?
Encrypt json data
It is absolutely NOT safe to store the encryption/decryption key into a static variable.
For this kind of communication, rather than one secret (symmetric) key being shared between the server and your app (which you have to arrange and keep track of), an asymmetric key pair is used. A key pair is a private key and the corresponding public key.
Let's pretend you only need to encrypt data going one way, from the server to the app: Your app generates a random, dispensable, temporary key pair, and sends the public key to the server. The server can then use that public key to encrypt the message that it is sending back to the app, without ever seeing the private key, and the message can only be decrypted with the private key, which never left the app. The public key cannot be used to decrypt, only encrypt.
If that key pair was created just for that exchange, then it can be thrown away and a new pair established for communication at any time (or after an expiration date/time).
That said, this is all done automatically, in both directions with https connections. So, setting that up would probably cover your needs. You're kind of re-inventing the wheel, otherwise. Unless you want that kind of strict control over the security. Even then, do both!
**Note: The above explanation is for conceptual purposes. Strictly speaking, https uses the Diffie-Hellman key exchange to send public keys between client and server (as stated above), but those are used to compute a shared symmetric key, which is more efficient, computationally.
Solution for your question is Certificate pinning. It prevents from MITM (man in the middle) attacks. Certificate pinning means that your app is verifying that the site the app is communicating with is the actual site by comparing the certificate presented by the site to one bundled in the app.
Please refer following link for more information
https://davidtruxall.com/android-certificate-pinning/
Yes, Communication between Android and Server can be secure and you sure can encrypt your JSON payload. Take a look at this git hub repo for how to encrypt your JSON payload. Encrypt your JSON payload(android project)
You can generate a public-private key pair and only share your public key with the client(Android). You can save the public key in whatever way you want to on the Android device. https, is also a good way to secure communication between client and server but take a look at this question to help guide you more.

Writing Simple Crypto using Different Passwords for Encrypting/Decrypting

I am posed with a problem which I have no idea how to solve, essentially I have these Files which one may enter a "write" or "read" password (these passwords are different), and I need to Encrypt and Decrypt these files using a common algorithm such as AES.
I know how to use crypto libraries (I will be using the ones provided in Java), however, I am unsure how to make this secure, or how to implement this.
I originally thought of storing salted hashes of these passwords for write/read, and then checking the entered password, however, I am unsure how the Crypto would work, if I have a keystore in say Java, won't it need a password so the keys don't appear in plaintext; I cannot have the keystore password in plaintext anywhere and I am not allowed to just make one up. Is there any well known solution to this problem I am positing which I can study?
Essentially: is there anyway to get access to encrypting or decrypting using a key derived from read/write passwords DEPENDING on the type of password entered, i.e. a user entering a READ password cannot encrypt, just decrypt.
Public-key cryptography has two separate keys, one to decrypt, one to encrypt. Usually, one of the two is public, though. In your case, you'd want to keep both private, and protect them with your two passwords. I suppose that would work for RSA (where the public key cannot be derived from the private key, which in other schemes it could).
So you'd be creating an RSA keypair, and store the two keys separately, protected with the two passphrases. That way you can control access to them individually.
Use RSA encryption to encrypt and decrypt an AES key. Use the AES key to encrypt and decrypt the content file.
The Java Keystore API doesn't support encryption of public key entries, but it does encourage the use of a password to protect the integrity of public keys. Your application could be written to use the "encryption" password to load a key store with the "public" encryption key, and fail if the wrong password is entered. Of course, a user can circumvent this outside the application, and get access to the public key using something like keytool or their own custom code. But you can't really stop someone from performing encryption with some key; why do you care if they use this key?
Private key entries would be encrypted with the "decryption" password. This common use case is well supported by the Keystore API.
If you are not allowed to store the key(s) elsewhere, I would store them in the encrypted file. I would encrypt the file with AES and then encrypt that key (the "file-key") twice by two AES keys (read-key and write-key and store:
[length-of-next-section] [file-key-encrypted-by-read] [length] [file-key-encrypted-by-write-key] [length] [file-data-as-encrypted-by-file-key]
FWIW, this is akin to how MAC OS X's "File Vault 2" whole disk encryption works -- the disk encrypted with a key, and 1 or more people's passwords are used to encrypt that key, thus any of these person's passwords can be used to "unlock" the disk at boot time.

Changing encryption algorithm

Does anyone know good tutorials to change PBEWithMD5AndDES encryption algorithm to AES for a Java application? Specially , I want to know what precautions I should take while changing this algorithm to more secure one. Any important test cases to check before and after algorithm changes. Another question is since I have used PBEWithMD5AndDES , most of the user passwords are encrypted using that algorithm. So if I change my algorithm to AES , how do I make sure that decryption of passwords happen with old algorithm while I can still use new algorithm for any new encryption.
Normally you wouldn't encrypt a users password, you'd just hash it with a salt instead.
Migrating from one encryption system to another is going to be a bit of a pain, as I see it you have two options:
During the upgrade process decrypt then re-encrypt all the passwords
Add a flag indicating the encryption method used. All existing passwords will obviously be set to the current standard. New users will be set to whatever method you choose and you can migrate other users when they change their password.
If you've already got data encrypted in format a, and you want to start using another encryption scheme, b, I can think of two ways to accomplish this:
Decrypt all of your data and re-encrypt it using `b`. This approach would be good when you can take your data store offline and "fix everything at once."
For each item you attempt to decrypt, try to decrypt it using `b` first. If that fails, decrypt it using `a`. The next time you try to encrypt something, make sure you use `b`. This approach could be used when you can't take your data store offline, but you want to encrypt all of your data using another algorithm. All of your data will eventually be encrypted using the other algorithm.
There's really no problem changing algorithms. What you need to do is decrypt the cipher text and then encrypt the resulting plain text with the new algorithm. That's straightforward. If you are going to perform this transition over time, I would suggest creating a new database table that keeps track of whether a particular entity (based on unique id) has been transfered to the new algorithm. If it has, then you simply use the new algorithm to decrypt it and you can forget about it, if not, then you use the old algorithm to decrypt it. Regardless though, all new encryption should be performed with the new algorithm.
Now, there's a second issue here. Why are you bothering to decrypt passwords? Just save the hash of the password and forget about it. If you are able to decrypt passwords, you introduce a potential vulnerability. If a malicious user can get a hold of your key you use to encrypt those passwords, then they could access the plain text of the password. Not only could the user then use that information to compromise your system, if your users use the same username/password combination for other sites, those accounts would be compromised as well. You should only store a hash of the password (SHA is a good one, don't use MD5) and then when the user attempts to log in, you hash the input and compare the two results. You have no need to know what the plain text password is.
you may look into ESAPI - java http://code.google.com/p/owasp-esapi-java/
ESAPI 1.4 was using PBEWithMD5AndDES, but in 2.0 they introduced AES
check their mail chain here
you may check the difference between the two implementations
PBEWithMD5AndDES is a method of taking a user's password and from it deriving an encryption scheme that can be used to protect further data. It is not a method of verifying a password, nor of encrypting one.
If you are only interested in password validation, then decrypt the passwords and replace them with a secure hash and in future match the hashes. You will also need your password reminder service to a password reset service.
The question is where is the password you are passing into the PBE algorithm coming from? If it is a fixed password for your application, then you just need to replace it and perform some kind of rolling upgrade. As an observation, if you are storing encrypted data as text, either hex or base-64 encoded, there are characters that cannot appear in the text output and which you can hence prepend to indicate a newer encryption scheme. For example the : character does not appear in base-64. That will allow you to identify what has been upgraded and what has not.
If the passwords are coming from the user, then each user has their own password derived cipher. In this case you can only re-encrypt whatever data has been encrypted with the user's cipher when the user provides their password.
The most direct replacement is going to be along the lines of PBEWithSHA256And256BitAES. Unfortunately, this is not supported by Java 6, so you will need a 3rd party JCE library such as Bouncy Castle. Bouncy Castle offers PBEWithSHA256And256BitAES-CBC-BC, which would be a suitable replacement.
The process of upgrading the cipher is a challenge. Whatever data has been encrypted with DES can only be decrypted with the user's password. I assume you do not have access to the passwords. This means you can only re-encrypt the data when the person who knows the password provides it. You are going to have a long period of time when your system contains a mixture of ciphers, so you need a way of identifying what is converted.
If we are talking about files, you could change the file suffix, or the folder they are stored in. If we are talking about BLOBs in a database, you could add an extra column to the database table to say what the encryption method is. If neither of those are possible you could add some form of header to the data to indicate that it has been encrypted in a new way. That's slightly risky as your existing data has no header and there is an outside chance it will match the new header by accident.
It may also be advisable to keep a list of which users have not yet had their data converted so you can prompt them to convert.

Categories

Resources