1

I need to use a signature for a JWT that needs to be created or verified on 12 different servers running in a load balanced environment. They all already have the same RSA Key Pair stored in the Windows Certificate Store used for serving the application over HTTPS.

This question has already been essentially asked here: Is D parameter of the RSA strong enough to be used as secret for HMAC calculation? but the focus there is on strength and/or purpose of encryption.

Initially I intended to sign the JWT using RS256, and I wrote the code and all was well....until I checked the output. Obviously (after the fact) the signature is rather long...2048 bits rather than 256. The total size of the JWT without the signature is probably only 2000 bits give or take, so it is basically doubling the size of the final token. The token will be used on multiple requests to downstream services, some of them with very small message bodies, so I am little reluctant to do this.

I have looked at various solutions DPAPI, .Net Protection and manually maintaining a secret encrypted with the public key. I need the solution to work in .Net and in .Net Core. All of them present issues around creating and managing the keys across multiple environments which are totally taken care of by the existing setup if I just use the D value as the secret. So...

Why should I NOT use the D value as my HMAC secret?

  • Why not at least make derivation from D? As you already use the keys for HTTPS. I think the flaw is not D strong or not, it is strong as the key is random and long enough. Discomfort comes that you use private key for different purposes, and do it directly. Also HMAC is a symmetric algorithm, that means verifier also should have the same key. RS256 on contrary, verifier shouldn't have private key. – VovCA May 2 '18 at 17:42
  • 1
    You can use a second fake RSA key for the HMAC secret (if you can’t find a way to,store an actual secret key). I would never use cryptographic material for,two different functions. This is also good,for,having different lifetimes and alllow key rollover. Besides you can even use a real,random string (not related to primes) in that fake certificate. – eckes May 2 '18 at 19:23
  • There is btw not much additional,security in using a certificate store if it allows you to actually retrieve the secret key bytes. So,you can also put your shared secret in a config file. – eckes May 2 '18 at 19:24
  • @VovCA Technically it would be a derivation. HMACSHA256 in .Net will hash a longer key down to 32 bytes before creating the signature. I guess I could use an additional parameter and do the derivation myself. – ste-fu May 3 '18 at 6:14
  • @eckes I do like the idea of the second RSA key for JWT signing, lots of benefits as you describe. Main issue is trying to convince ops team to go to the extra effort to install and maintain extra certs. – ste-fu May 3 '18 at 6:19
1

This is one of those cases, where I don't believe there is any known way to exploit this. So you could argue this is secure. But the problem is, this is not something that is proven secure and it is not what these functions were designed for. Therefore it is likely there may be a way to exploit this. And if one is ever found, it could reveal your RSA key, which is the most important key you have as a web server. That is why this is NOT CONSIDERED SECURE, even if there may not be a way to exploit it. Don't do this, there are better ways.

Also, it does open a new way for the RSA key to be brute-forced, which may or may not be faster then computing it from the public key.

  • Thanks for the answer. As per VoVCA's comment. How would you feel about using the a derivation function? Eg. Key = PBKDF2(Salt = SecretFromConfig, Password= D value, Iterations = 1000) – ste-fu May 3 '18 at 6:27
  • @ste-fu It would certainly be better, though can I ask why you don't just generate a secret and distribute it between the servers? – Peter Harmann May 3 '18 at 7:24
  • As a developer I don't have access to the live servers, and I should also not have access to the HMAC key. There is an operational overhead to generating and maintaining / rotating secrets on the live servers, which I don't have the authority to enforce. The issues are more organisational than technical. – ste-fu May 3 '18 at 8:24
  • @ste-fu You can have the servers generate and distribute them on their own, can't you? Easiest way to do it: have each server generate it's own hmac key, then have the other servers make a request to api of the others server to get the key. You can encrypt it with your server RSA key and at least you are not using it for something non-standard. Or you can make sure only one HMAC key is used. Either way, it should be better. – Peter Harmann May 3 '18 at 8:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.