What to do with Key and Salt when encrypting on the client? - encryption

I'm encrypting some data that needs to stay on the client, and so will the Salt, Key and IV. Is there a standard way of handling this data on the client to prevent people from discovering it and encryption your data?
I can think of plenty of things to obscure them, but there must be an industry standard way of dealing with this issue.

There's no additional security risk if the IV and salt are known. IV's are safe to store in the clear, and salts are to help prevent precomputation and rainbow tables.
So you're really just talking about the key. There's a couple solutions, each with it's own tradeoffs. In your question, you only mention you need to encrypt data on the client. Does the client not need to decrypt?
If this is a Windows client, you can use the Data Protection API to protect the key under the users credentials.
Protect the key with a passphrase. If you don't mind entering a passphrase each time the client needs the key, this can offer reasonable protection, and it's supported in most cryptosystems like OpenPGP.
If the client only needs to encrypt, you can use a hybrid approach with public keys (like OpenPGP). In this case, you only store the public key on the client, and the private key somewhere safe. When you encrypt data, you'll generate a random symmetric key, and encrypt that under the client's public key. Now if someone compromises the machine, they won't be able to decrypt any of the session keys.
Use specialized hardware like a hardware security module or smart card. This is the most expensive route, but depending on your threat model might be viable.

Related

How JWE works with Request Object in OIDC

I wanted to use encrypted local PASETO tokens for the Request Object in the OIDC, but it turns out that I need to store the key somewhere to decrypt this request object, and it must be available unencrypted/unhashed as it will need the Request Object to decrypt. So I will have to store it as plain text in a database? Pretty dangerous. So I started to wonder how JWE works, but the documentation from https://datatracker.ietf.org/doc/html/rfc7516#section-5.1 about JWE encryption is quite confusing for me. Does JWE solve this problem of storing a symmetric key in a database as plain text or does it have other ways?
There are a few different solutions here, which solve different problems:
ENCRYPTED JWTs
These can be used when the app wants to prevent information disclosure. They are issued by the Authorization Server, which uses a public key to encrypt them. There is then a burden on the app to maintain a private key to decrypt them. See the Encrypted ID Tokens for some example usage.
REQUEST OBJECTS
These are often used to protect against man in the browser tampering. The app only needs to deal with public keys, which it already has access to, so the solution is easier to manage. Newer standards such as PAR and JARM are used, as in this summary.
JWT INFORMATION DISCLOSURE
If you want to avoid revealing sensitive data in access token JWTs, then the usual technique is to return only opaque access tokens to internet clients. This is easier to manage than encryption. See the Phantom Token Pattern for how this works.
SUMMARY
I would usually avoid introducing key management into apps. Aim to manage this in the Authorization Server instead.

Are there vulnerabilities in using an AES encrypted token for authorization

We are currently implementing our authorization to a restricted resource by encrypting specific information and the password given to create a token using AES/CBC/PKCS5Padding encryption with a 128bit private key known only to the server.
Inside this token we place
hash of password(sha-512 and a random salt of 64 bytes)
expiry date
valid flag (boolean)
creation date timestamp
The server then encrypts this information using its private key and passes it to the client.
The client requests the restricted resource and presents this token to the server which decrypts it and validates the contents to provide access to a restricted resource.
We wish to do it this way to avoid keeping information regarding issued tokens on our server to avoid potential resource limitations.
Since I am not a security expert any help showing possible vulnerabilities or why this is a bad idea would be much appreciated.
Just send the hashed version for comparison.
Just using a hash function is not sufficient and just adding a salt does little to improve the security. Instead iterate over an HMAC with a random salt for about a 100ms duration and save the salt with the hash. Use functions such as PBKDF2 (aka Rfc2898DeriveBytes), password_hash/password_verify, Bcrypt and similar functions. The point is to make the attacker spend a lot of time finding passwords by brute force. Protecting your users is important, please use secure password methods.
See Toward Better Password Requirements by Jim Fenton.
[DRAFT NIST Special Publication 800-63B Digital Authentication Guideline](
https://pages.nist.gov/800-63-3/sp800-63b.html)
NIST’s new password rules – what you need to know:
https://nakedsecurity.sophos.com/2016/08/18/nists-new-password-rules-what-you-need-to-know/ by Sophos

Why is it that web developers do not do this with databases?

I hear about all these websites getting hacked with sql injections and stuff. What's preventing them from encrypting the hashes with a 32 character string? If I were a hacker and I managed to get the database and I came across encrypted hashes I would not be able to do anything with the database as I do not know the encryption algorithm and the key.
As long as the key being stored securly everyones account would be safe.
Your idea of encrypting the hashes will indeed improve the security of the users password, but you should understand what exactly you are solving with this measure and what not.
First and most important, encryption on passwords is usually frowned upon, because it is a weak protection. If an attacker has the key, he can instantly discover all passwords. So the encryption does not relieve you from properly hash passwords with a slow algorithm like BCrypt, SCrypt, PBKDF2 or Argon2.
But your question was about encrypting the hashes. There is a case where even properly hashed and salted passwords can be recovered easily. If the user has choosen a very weak password, a dictionary attack will reveal them very fast anyway. If the hashes are encrypted though, the attacker needs the key, before he can start with the dictionary. This leads us to the following situation:
Encrypting the hashes will protect weak passwords, as long as the key stays secret. This is always the case when the attacker has no privileges on the server, examples are SQL-injection, disregarded servers, backups, ... I tried to describe this at the end of my tutorial about safely storing passwords.

Public Key Encryption vs HSM for storing encryption keys

Let's say I have sensitive data in the database server that needs to be encrypted (i.e emails, etc..) and I want to make sure that in the event that the server is compromised, the attacker shouldn't be able to decrypt these data (at the very least make it harder).
I've read some solutions online, and it seems like I can either
Use Hardware Security Modules (i.e. Amazon KMS/Vault) to having a separate server handle encryption/decryption.
Use Public Key Encryption (where the public key in database server encrypts data, and a private key is stored in separate server that solely handles decryption)
What are the tradeoffs of each other and which one would you choose?

Does encryption add any benefit if I'm using SSL?

I recently stumbled across this article on securing Web API endpoints.
If I'm using SSL, is there any advantage to encrypting the user string in the header? What are the risks if I include the user key (Id) as plaintext instead of ciphertext?
TLS is transport-level security. I.e. the data is not secured by TLS before the data reaches the transport and after that. If your data is long-term and/or you keep them elsewhere besides using during the transport session, then it might make some sense to keep them encrypted (and then transfer them encrypted if possible). If your data lifetime is short and the data makes sense only during the transport session, then there's no much sense in encrypting the data besides TLS.
The author of the article is basically combining the concepts of a user identifier and a user secret into a single cryptographic token. If you choose to send a user identifier in plaintext instead, then that user identifier must be kept secret (just as the token must be kept secret). As long as that secrecy is maintained there is no advantage to using the token.
Note that this system doesn't seem very secure as presented. If an attacker can guess a valid user identifier then they can generate a valid token. The author is basically using RSA as a glorified hash function. I'd recommend you look for another reference.

Resources