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.
Related
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?
Lately I have been reading some about JWT/JWS and JWE.. however.. one part I still dont get is that Im quite sure that I somewhere have read that they all should be "stateless", is this true?
My take on this would be that JWS and JWE would require a shared secret between the "acquirer" and the "issuer" to be able to decrypt the payload (and CEK and what not depending on JWS or JWE).
So my question is.. is JWS and JWE truly stateless? And if thats the case, then how come we dont need to store a secret between the "acquirer" and the "issuer"? Or is the kid used for fetching our secret from for instance a database to decrypt the payload and/or CEK?
To clarify,
Is there a shared secret between the issuer and the acquirer when using JWS and/or JWE to decrypt and encrypt the token? Is this secret stored in a database on the issuer to be able to decrypt the payload and/or the CEK or is the secret/key used to decrypt and encrypt shared some other way?
This question is based on the following article regarding JWT,JWS and JWE:
https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3
You are right: Depending on your application, it may be stateful.
From my point of view, you could ditinguish two cases:
Your application issues JWE or receives JWS
Your application issues JWS or receives JWE
With the first use case, the JWS signature can be checked using the issuer public keys. These keys are (broadly speaking) shared with the parties by the issuer (this what Google and other authorities do). Same goes when you want to encrypt a token (JWE) to that recipient: you will use its public key.
With the other use case, your application will need to have access on a key set with private keys. Those keys are necessarily stored somewhere (a DB, an environment variable...).
When shared keys are used (rarely used with 3rd parties), you may be in the use case #2 as both the issuer and the recipient have to manage the shared key.
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.
In my app I give users the ability to store data and share it with specific other users. We are going to add a layer of security by encrypting the data stored and using a users specific public key to decrypt and view the data. What is the best way to enable those other users with access to decrypt and view the data? Use the public key to get a shared cipher perhaps? I'm not sure on how to approach this :S
Well, using a user-specific key is not the correct way to go if you want to share some but not all files. Instead, you'd want a file-specific key.
In turn, you encrypt this file key with the public key of the owner. If the owner wants to share the file, he decrypts the file key with his private key and re-encrypts it with the public key of the person he wants to share the file with.
This means you use symmetric key cryptography for the files, and asymmetric key cryptography for the key management.
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)