Is there practical difference between HS256 and HS512 encryption algorithms, or is the additional security from longer key redundant compared to already unbreakable key? Which one should I use to encrypt the JWT token?
Is it even possible to use HS512 encryption with auth0's java JWT?
The algorithm is used to perform a digital signature (not encryption) over the header and payload of the token. If you want to encrypt the token payload, you need to apply the JWE standard (see RFC)
Is there a practical difference between HS256 and HS512 encryption algorithms, or is the additional security from longer key redundant compared to already unbreakable key? Which one should I use to encrypt the JWT token?
HS256 means HMAC-SHA256. The difference with HS512 is the strength of the hash methods themselves. You can take a look at the keylength.com website and this answer. You will see that even SHA-256 has quite a large security margin. What's more, the HMAC algorithm is pretty much oblivious to attacks on the underlying hash algorithm. So even you can use HMAC-SHA1 safely.
Is it even possible to use HS512 encryption with auth0's java JWT?
I took a look at the code, and it is possible (but not documented). Use something similar to
JWTSigner.Options options = new JWTSigner.Options();
options.setAlgorithm(Algorithm.HS512);
jwtSigner.sign(claims, options);
Is it even possible to use HS512 encryption with auth0's java JWT?
You could do something like this:
Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
Example taken from here: link
Related
I understand that WebauthN is designed to perform authentication, but I'd like to use my Yubikey to create symmetric encryption keys to encrypt content on my web browser without relying on a backend server.
Here's my approach:
During the assertion challange ( navigator.credentials.get({ publicKey }) ) the Yubikey signs a challenge string that the client sends to the authenticator.
I extract the signed challenge, hash it with SHA256 and use it as my new symmetric encryption key for AES256 encryption.
As long as the same challenge string is sent to the Yubikey, the encryption key will always be the same.
In order to be able to decrypt the content on the web browser. I would have to be in possession of the Yubikey and the challenge string for 2 factor authentication.
Is there anything wrong with this approach?
Why don't you use the Web Crypto API?
This API is designed for cypher operations on client side and is suitable for your use case (client side encryption). It is supported by all recent browsers.
Note that the main concern you may have is that this API does not supports hardware devices (smartcards, security tokens...).
However, your Yubikey is certainly capable of generating a secured static password you can use as a master key you will derive to encrypt/decrypt your data.
Perhaps you could leverage the hmac-secret extension (https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#sctn-hmac-secret-extension)?
No. This is a bad idea for these reasons:
RS256/ES256 are not deterministic signatures. So you will get a new, random signature every time.
Even if you could, there are things like XSS, and this would be broken swiftly.
Use crypto API as mentioned above.
HMAC-Secret is reserved for Platforms at the moment. You can not access it via WebAuthn API.
In the future, there is a large blobs functionality, and largeBlobsKey... But this is a very long future...
You could (mis)use the user.id parameter of the public key request payload, i.e., the user object in the example here: Web Authentication API (example) like this:
Use Web Crypto API to generate a symmetric key
then use that key as user.id in navigator.credentials.create({ user: {id: YOUR_KEY } }) to store the key in the authenticator
store the returned key id/rawId somewhere in your application
To retrieve the key you can use navigator.credentials.get({ publicKey }) by supplying the rawId
Problem
I want to sign and encrypt (effectively, obfuscate) some information ('token') on my server (a trusted environment) and send the cyphertext to a client machine (not quite trusted environment) to be read and verified by my client-side software. This type of the environment allows me to have a private key on the server for asymmetric signing, but I cannot 'hide' a secret key for symmetric signing on a client side.
Alternatives
I chose to use JWT as a standard and Nimbus JOSE+JWT library as an implementation for signing and encryption. Nimbus library provides two options for sign + encrypt: nest JWS into JWE or use JWE with authenticated encryption algorithm (A128CBC_HS256, A192CBC_HS384, or A256CBC_HS512). Algorithm Selection Guide for Nimbus states:
Encryption in JOSE is always authenticated, meaning that ciphertext’s integrity is protected from tampering. Authenticated encryption thus makes nesting an HMAC JWT inside a JSON Web Encryption (JWE) redundant; use just JWE encryption.
However, AxxxCBC_HSxxx encryption methods use only symmetric keys. Additionally, replacing direct JWE algorithm with RSA JWE algorithm should not help, because an abuser can generate CEK (consisting of encryption key and key for HMAC) themselves and encrypt it with a public key.
Question
Despite the quote about the redundancy of nested JWTs, I concluded, that for my case JWE+JWS nesting is the only workable approach. Am I right?
Clarifications
Every content encryption algorithms (AxxxGCM and AxxxCBC_HSxxx) use a symmetric key (CEK). This key is determined by the key encryption algorithm and its key management mode (random CEK, key agreement, direct key...).
You are right, contrary to the AxxxGCM algorithms, the AxxxCBC algorithms are not authenticated encryption algorithms.
However, the RFC7516 section 5.1 item 15. (specification for JWE) introduces a tag that allows to authenticate the cyphertext and protect the integrity of the protected header (that is why the AxxxCBC algorithm is used with the HSxxx).
This is confirmed by the table in the RFC7518 section 5.1. Details are given in the next section.
In any case, you will need 2 algorithms for JWE computation:
The key encryption algorithm: you mentioned you have an asymmetric key so I guess you will chose an RSA or an ECDH-ES algorithm depending on your key type.
The content encryption key: AxxxGCM or AxxxCBC_HSxxx algorithms. With the JWE specification both offer an authenticated encryption. Personally I prefer AxxxGCM algorithms because they are faster in my environment.
Answer
You indicated that you want sign and encrypt but you cannot hide a secret key on client side thus the signature will not be guaranteed.
If you only encrypt (JWE only), your server will not be able to verify the issuer of the token.
This is a Paw question. Is there a Paw encryption add-on that supports AES working in the commonly used modes and lengths?
I have a request that includes encrypted fields. These fields are AES encrypted. The key is 128 bits long. The encryption mode is CBC. The encryption is performed by the mobile app. The key is inside the mobile app.
At the moment, I capture the requests in Burp, Import them into Paw, and then I have the valid request.
I know the plaintext. I know the key. I know the algorithm. I know the Initialization Vector. There must be a better way.
I could not find anything on: https://paw.cloud/extensions/
There are two new DynamicValues that should allow you to do what you wish to do:
AES Decrypt
AES Encrypt
They are based on an npm port of the CryptoJS library and should expose most of the API for decryption/encryption in AES.
Here's a couple screenshot to show you what it looks like:
Since the DynamicValues are quite recent, there may be a few issues with them. Don't hesitate to report them.
I want to do searching on encrypted data. Which means that there is the need to have the same ciphertext every time I encrypt the same plaintext. I.e. think of a list of encrypted names and I want to find all "Kevin"'s in it. I would now encrypt "Kevin" and search the database for the encrypted text. All hits will be "Kevin"'s — but still only the one who has the password knows.
Now my question: What about security if I use the same salt and IV (to get the effect described above) all the time? Is the encryption still secure? Or is there any other method to do searching on encrypted data?
If you want to do a deterministic encryption then you should use an encryption mode
that has been designed for deterministic encryption (and not modify an encryption mode designed for something else).
One possibility is the SIV encryption mode described in
RFC 5297.
(Of course, deterministic encryption has its drawbacks, but discussing this is not part of this question.)
I need to implemented security for client-server communication. I have implemented the following hybrid cryptosystem
To encrypt a message addressed to Alice in a hybrid cryptosystem, Bob does the following:
Obtains Alice's public key.
Generates a fresh symmetric key for the data encapsulation scheme.
Encrypts the message under the data encapsulation scheme, using the symmetric key just generated.
Encrypt the symmetric key under the key encapsulation scheme, using Alice's public key.
Send both of these encryptions to Alice.
To decrypt this hybrid ciphertext, Alice does the following:
uses her private key to decrypt the symmetric key contained in the key encapsulation segment.
uses this symmetric key to decrypt the message contained in the data encapsulation segment.
I am using RSA For a public-key cryptosystem, and AES for symmetric-key cryptosystem. Every thing works fine, but I am not sure how to handle AES initialization vector. Currently, I am concatenating the AES key and initialization vector encrypting it with the public key and sending that to server.
I just wanted to get some opinions about this approach. How this problem is solved by other communication protocols SSL etc.
Thanks.
You don't encrypt the IV. Bundle it with the encrypted key and send it (in the clear) to the recipient.
Standards for this do exist. This scheme is called "KeyTransRecipientInfo" in CMS (upon which S/MIME is based), and PGP offers a similar mode. TLS also includes the initialization vector as a parameter in the key encryption algorithm identifier, using the same ASN.1 syntax as CMS. A robust, open-source library to perform this operation is available for many, many platforms.
At the very least, studying the CMS specification might help avoid some of the many pitfalls in a home-brew implementation. See §6.1 and §6.2.1 of RFC 3369.
I've done the same thing, and I handled it the same way - concatenate the AES key with the IV and encrypt them both.
You could also just send the key and use the key itself to generate an IV - for example by using the first 128 bits of a hash of the key as the IV. That should be OK security-wise as long as you are generating a new AES key for each session and not re-using the same AES key over and over with the same IV.
There is no reason to encrypt the IV - you can send that in the clear. Just make sure you pick a new one each time (the same way you do the AES key).
That said, it is often convenient to package the AES key and IV together. Encryption of 16 bytes ain't that expensive.