# Compromise between HMAC and Digital Signature, by encrypting and sending secret key?

For achieving stateless authentication tokens (like JWT), is there a compromise between the performance of HMAC, and public key distribution of Digital Signature?

Scenario:

• Sender is a centralized authentication server.
• Receiver is an distributed/elastic pool of stateless web services.
• The issue I have with HMAC alone is distributing the secret key to the receivers.
• Receivers only store Public Key in long-term storage.
• The issue I have with Digital Signature alone is the performance for large messages.

Could the sender somehow generate the HMAC secret key dynamically for each token, and then encrypt it using Private Key? That way receiver could decrypt HMAC secret key with the Public Key, and then verify the signature.

Something like:

JWT = BASE64(header).BASE64(M).BASE64(HMAC(K,M))
M = Claim || Encrypt(K)


What are the drawbacks? What are the other approaches to distributing the HMAC secret key with receivers?

• Possible duplicate of HMAC vs ECDSA for JWT – mikeazo Dec 18 '15 at 15:28
• There may be some questions here though that are not answered by the linked question and answers. Can you clarify the differences? – mikeazo Dec 18 '15 at 15:29
• I've evaluated both HMAC and Digital Signature (regardless ECDSA/RSA/DSA), and neither fit my needs. It's not a 'vs' question, it's a 'what are the alternatives'. For performance reasons, I don't want to do asymmetric cipher across payload M. I'm looking for a performance compromise, to retain the speed of HMAC symmetric cipher, without compromising security. – user29944 Dec 18 '15 at 17:20
• Thanks, that helps. I don't see how your proposal (encrypt the hmac key with the private key) helps with the performance issue at all. Now, if you had public keys of each of the distributed/elastic pool, you could encrypt with their public key (which is often more efficient than a private key operation). But that opens another can of worms, key distribution on the elastic/stateless web servers. – mikeazo Dec 18 '15 at 17:26

No, this will not work, for two fundamental reasons:

1. You cannot "encrypt with the private key and decrypt with the public key" in any meaningful sense.* And if you could, it would be totally useless, because the public key is, by definition, public — if you could decrypt with the public key, so could anyone else.

In particular, in your scheme, anybody with access to a "signed" message could decrypt the MAC key (which they need to verify the message, anyway), use that key to forge other messages, and attach the same encrypted MAC key to them.

2. Even if you scheme worked, it would provide no performance improvement over conventional signature schemes. Specifically, the standard way to sign messages of arbitrary length is to hash them with a cryptographic hash function, and then sign the hash value. Thus, for long messages, the performance of conventional signatures is dominated by the time needed to compute the hash value, which is approximately the same as (and, in fact, strictly less than) the time needed to apply HMAC to the same message using the same hash.**

*) Yes, I'm aware that, for the RSA cryptosystem, signature generation and verification are very similar to encryption and decryption, except with the public and private exponents swapped. This duality is peculiar to RSA, and does not extend to most other public-key cryptosystems. And even for RSA, the duality breaks once you introduce message padding, which is needed to turn "textbook RSA" into an actual secure cryptosystem.

**) HMAC does place somewhat lower security requirements on the hash function than signatures do (in particular, it does not require the hash to be collision resistant), so you could potentially use a faster and less secure hash for HMAC. That is, assuming your scheme worked in the first place, which it does not. And, given that there exist plenty of modern hash functions that are both fast and secure, you'd still be trading a lot of precious security margin for, at best, a very modest gain in speed.

• Accepted based on fact that time to compute digital signature being strictly less than time to compute HMAC, using the same hash. – user29944 Jan 18 '16 at 18:45
• @user29944: To be precise, I meant to say that the time needed to hash the message is strictly less than the time to HMAC (or sign) it, simply because hashing the message is one step in both HMAC and in signing. Typically, the full signing process will be somewhat slower than HMAC; but the difference is by a constant amount (depending only on the signature and hash algorithms, and on the signature key length), and thus becomes relatively insignificant for sufficiently long messages. – Ilmari Karonen Jan 18 '16 at 22:07