How JWE works with Request Object in OIDC - encryption

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.

Related

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

How to use AEM cryptosupport API at clientside?

I am planning to use cryptosupport API to encryp/decrypt certain cookie keys bearing PCI/PII customer data. I am setting/reading these cookies at both client and server side. At server end (java), I am able to call API and encrypt/decrypt. How do I call the API from clientside (javascript) ? The usage is quite huge at clientside and I dont want to make ajax calls to server.
Is it advisable to use this API with requirement of encrypting cookie data used at both client and server side?
Or is there simpler encryption API for this purpose?
It is a server-side AEM capability only.
And think about it--if you were able to call an API to decrypt a cipher on the client side (JavaScript), what security would it provide? End users could easily also decrypt the cipher and see the secret, so it really would defeat the purpose of having an encrypted secret.
See What encryption algorithm is best for encrypting cookies? which says
Since this question is rather popular, I thought it useful to give
it an update.
Let me emphasise the correct answer as given by AviD to this question:
You should not store any data that needs encrypting in your cookie. Instead, store a good sized (128 bits/16 bytes) random key in
the cookie and store the information you want to keep secure on the
server, identified by the cookie's key.

Which to use between RS256 and HS256 for ASP.NET web client?

I'm developing an ASP.Net Core web application and will be using Auth0 for user authentication.
I'm having a hard time figuring out if my JSON Web Token Signature Algorithm should be RS256 or HS256.
From the information that I have found, I still can't make heads or tails of it. Any ideas?
Even though both algorithms make use of SHA-256, they are fundamentally different:
RS256 (RSASSA-PKCS1-v1_5 using SHA-256) relies on generating a digital signature with a specific private key.
HS256 (HMAC using SHA-256) relies on a shared secret plus the cryptographic hash function (SHA-256) to generate a message authentication code (MAC).
Validating tokens issued with each of the previous algorithms implies that for RS256 the entity doing the validation knows the public key associated with the private key used for signing, while for HS256 it implies that the entity knows the shared secret.
Choosing between one versus the other is then usually motivated by the characteristics of the applications that will validate the issued tokens.
If you want to validate a token on a browser-based application, the use of HS256 is automatically ruled out because that would imply you would have to include the shared secret in a place anyone would have access, making it completely useless because now anyone with access to the code could issue their own signed tokens.
In conclusion, if token validation is done on a controlled environment (server-side) you may go with HS256 because it's simpler to get started. However, if token validation is done on hostile environment you need to go with an algorithm based on asymmetric cryptography; in this case that would be RS256.

Why is encryption considered safer?

This has puzzled me for a while now. I don't have a broad understanding on encryption, but I understand the principle.
For the sake of an example, let's assume I have a program whose sole purpose is to post a random user's input to my private facebook profile. Now to do this, the program must have my login information to facebook (if this is not the case, assume another third-party application). This information, or credentials, must be stored somewhere, since the program's post method would be done without administration.
I know it is a bad policy to store the login credentials in the code as plain strings, as the compiled code can be decompiled and my credentials would be readable. The recommended solution is to store them in a separate file, encrypted.
As far as I understand, the encryption / decryption needs a key that also needs to be stored somewhere. Can't this key and the encryption algorithm be read from the decompiled code and used to decrypt the credentials?
Is the benefit of storing the credentials encrypted based on the extra step on decompile-decrypt, or have I drastically misunderstood something?
There are 2 ways one could check supplied credentials when you have encrypted version:
Decrypt the encrypted version; this would obviously require storing the tools necessary to decryption, which is unsafe
Encrypt what you are trying to check, and see if it matches your encrypted version. This does not require the ability to decrypt anything.

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