I would like to AES encrypt some users profiles info.
When a user registers, I use the password he provides, I compleate it to 16 bits with zeros to have the required key lenght (16 bit) for AES if the password does not have 16 in lenght, then I encrypt all his data profile with that key. I know that at this point my AES keys will be secure because no one knows them except the users them selves.
When a user logs in, I take his password do the same 16 bit process and decrypt his data. The problem I have is with password recovery, if the user forget his password, the data is lost forever. Is there a better way or a work around this issue?
Thanks.
Your AES key "derivation" is not secure, you should use password hashing (or, to be more precise, use a password based key derivation function - PBKDF) instead of padding with zero's. A password is not the same thing as a key, which should consists of 128 or more randomized bits.
Instead of recovering the key (or password) you could encrypt your data with a random data key. Then you can in turn encrypt this data key with the key of the user. You can additionally encrypt the data key using a public (RSA) key, of which you keep the private key safe on detached storage or somewhere in the back office. The encryption of one key with another key is called key wrapping.
Some data you may want to keep private to the user, in that case simply do not encrypt with the public key in the back office. You could possibly encrypt this kind of data at the location of the user instead of on your server.
Related
I have to store sensitive data on the server for a web application. The data has to be viewable in plain text later so I can't hash it.
My question is what would be the most secure way to apply the algorithm / where to store my key. I could store it locally on the server or do you have any ideas to store this data as secure as possible while still being able to decrypt it?
We cannot decrypt a cipher text without a key. Hashing is an irreversible process. It wont work in your scenario. There are two types of cryptography techniques: Symmetric and Asymmetric.
Asymmetric cryptography is maintaining two keys for everyone:public key and private key.When you want to communicate with someone, you should encrypt the plain text using their public key and they will decrypt the same using their private key. When they want to communicate with you, they will encrypt the plain text using your public key and you can decrypt the same using your private key. So every party should hold two types of keys.
Symmetric Cryptography is maintaining a single key for a communication. The single key will encrypt and decrypt the data. When two parties wants to communicate, they should have a shared secret key (common key). When you want to communicate, you can encrypt the plain text using the key and they will convert back the cipher into plain text using the same key.
In your scenario, you can use Symmetric cryptography techniques such as AES,DES etc., You can maintain a separate key for every user. You can use that key for encryption and decryption. The keys can be stored in another database. whenever you want to display the password in plain text, you can take the key for the user and decrypt it using the same cryptographic technique.
I am working on Encrypting some data using AES 128bit encryption algorithm (Symmetric Encryption Algorithm).
Problem I am facing with this is generating a Key ? As I have mutliple Users and I don't want to share the common key across the users.
Is there is any possibility to generate passphrase in such a way that it is not common to all and can be passed to AES to decrypt/Encrypt the same data?
Example:
lets assume I have a table with employee and their salary. I want to encrypt Salary Column of Employee with AES encryption.
Now when Someone authorized from HR wants to see the salary of Employee they can check, but they should have their own Key (not the common Key).
One possible solution is to create an encrypted version of the master key per user.
So you will:
Encrypt your data with a "master key"
Encrypt your "master key" with a "personal key" (one for each user)
Then, when a user provides its personal key, you use it to decrypt the stored and encrypted master key, and then use that to decrypt the data. This way the encryption for the data can be done with always the same key, and you can regulate access with the personal keys.
This assumes though the master key and encrypted data never leave the server, you will have to decrypt on the server and send unencrypted to the user (but of course use a secure line for that, against eavesdropping).
There is no way to do this if you want to send the data to the user encrypted.
Now when Someone authorized from HR wants to see the salary of Employee they can check, but they should have their own Key (not the common Key).
Using symmetric encryption - effectively there is only a single data encryption key (DEK). The DEK can be random and content specific. You cannot have multiple keys to decrypt the same encrypted content.
What is commonly done using asymmetric encryption, when someone authorizes (shares/assigns) an encrypted content to a user, the DEK is re-encrypted by the user's public key, so only an authorized user could decrypt the DEK and then content (though - the DEK is the same for all users).
when user logs in I will ask them Key
To log in the user anyway needs to provide a secret (its user password or other credentials), so - do you really need to go through all the hustle? Isn't enough to encrypt data at REST with some system-specific master key and provide the encrypted content only to an authenticated and authorized user?
I'm searching for a specific way to encrypt my data.
I want to encrypt it with my password and decrypt it with that.
Later I want to gain other people access to chosen parts of my data with their passwords.
Is there any other way than to decrypt the data everytime I add a new "reader" and encrypt it all again with a "mix" of all passwords?
And than the big question is how to decrypt without knowing the passwords of everyone?
And than I thought of another problem. How to validate that the given/login password is correct?
I thought the following might work without saving the actual password or the encryption password:
Get a password ; "Thats an amazingly bad password"
Use the hash as encryption and decryption key ; hash(salt + "Thats an amazingly bad password")
Save the hashed hash as validation for the password ; hash(hash(salt + "Thats an amazingly bad password"))
What do you think about it?
Thanks for help everyone
Encrypt the data once with a secure key such as random bytes.
For each user encrypt the above key using the user's password (properly extended), save that in a file or DB under the userID and a salted/hashed password for authentication.
To access lookup the user's entry verify the supplied password with the salted/hashed password, decrypt the data key with the user's password.
Decrypt the data with the data key and return to the user.
Side advantage: A user's password can be changed without changing the actual key the data is encrypted with.
For the second part:
Do not hash(hash(salt + "Thats an amazingly bad password")), use a password extension method such as PBKDF2 on the user supplied password for the encryption key. Such methods take a salt and a password and iterate many times to make the operation slow, somewhere around 100ms seems to be a good target.
Hashing a hash does not accomplish anything other than adding a trivial amount of time to the operation.
What encryption algorithm can use 2 keys:
admin - encrypt & decrypt
and
user - only decrypt ?
You can do this with RSA by using the private key for encryption (as if you would be signing). The tuple (d,n) would be the admin key (normally named private key), (e,n) would be the user key (normally named public key). The admin key is used for encryption, the user key for decryption. Only the admin is in possession of the admin key, while both the user and the admin know the user key. Now only the admin can encrypt, while the user can only decrypt.
Note that I deliberately chose the exponent d for the encrypting admin key and not vice-versa, because e is usually chosen to be very small for better performance, and if you'd do that with the admin key instead of the user key, then the system would be broken.
Note that if you construct a hybrid system for this, the desired decrypt-only property breaks, because the user can get to the symmetrical session key as well and modify the message.
I suspect you might want the decrypt-only property to actually achieve authentication of potentially large amounts of encrypted data (i.e. so that the user knows the data must come from the admin and has not been tampered with). If so, what you really need is a more complex scheme with a proper digital signature (providing authentication) and some form of encryption for confidentiality, e.g. hybrid using a symmetrical cipher for bulk encryption and e.g. RSA for encryption of the symmetrical key.
However, you should be very careful when designing cryptographic systems like this, there are a lot of things which can go wrong and completely compromise the security of your system. Seek expert advice.
Edit: This is incorrect (see Daniel's comment).
You can modify any algorithm to allow two keys by generating a session key, using that to encrypt the payload, then using the two keys to each encrypt the session key.
For example, if Ak is the admin key, Uk is the user's key, Sk is a random session key, and e(k, p) is a symmetric encryption function, then you would use:
ciphertext = e(Ak, Sk) . e(Uk, Sk) . e(Sk, p)
I need to encrypt content in my web application on a per-user basis.
I, the root user, do not want to have access to users' content, period.
How can I make it so users are the only ones with access to their content? Perhaps I can make it so a hash of their login password acts as an encryption and decryption key (then their password is stored one-way hashed in my database, and the encryption/decryption hash is generated from their raw password on login and stored in a local cookie)? But what if they change their password? Then I have to update all their content which could take a lot of processing power.
Is there an encryption method that would provide this, without having to re-encrypt their content if their password changes? Something similar to ecryptfs on Linux, perhaps? Is researching ecryptfs a good place to start?
Is making it so only the user can access their content on my servers (and not even me) even feasible?
Process:
Generate a random secret to encrypt their content.
Using their provided password encrypt the random secret from #1.
Store their password as a one-way hash (with salt, maybe multi-hash).
Upon Password change:
Re-generate the value from step #2.
Re-generate the hash-cache from step #3.
Upon Login:
Hash password and check against hash generated in step #3.
If password matches - use actual provided password to decrypt random secret from #2.
Use random secret from #2 to unlock data encrypted in #1.
Notes:
No one can decode the data without knowing the random secret (#1). Random secret can only be unlocked with user's actual password (#2) (short of brute-force). User's actual password is only known in one-way hashed form (#3) so you can confirm it's the same, but cannot decode it and recover #2.
A forgotten password process is not possible (you can regenerate #3, but random key in #2 is now lost as is everything locked in their vault).
You don't have to re-encrypt everything in step #1 every time they change their password, only the (simple/quick) random secret from #2.
If you cache their provided password, or the random secret generated at step 1, or their (decrypted) content anywhere you could cause data leaks.
You're spot on that you need to use their password as a key.
I wouldn't monkey with ecryptfs because an encrypted file system isn't the best solution. You wouldn't want one user's data to be encrypted with the same key that another user used.
When you encrypt the data, you should generate a random string to use as salt. This prevents someone from using a pre-generated list of hashes to decrypt your data. It also changes the hash of two people who might use the same password.
When a user changes their password, you'll have to re-encrypt the data and generate a new salt value. This is the level of security I would expect as a customer, knowing that when I change my password, I'm re-encrypting all of my data to prevent someone from trying to brute force my key.
You can store the salt value in your database unencrypted.