2
$\begingroup$

I am working on a project that uses PAKE (SRP) for authentication. When we send the M1 to the server we are encrypting the payload using AES-GCM. I mention SRP only to set the context:

  1. A message is being sent to the server with content we want to protect
  2. The client and server have a unique (one-time) symmetric key shared between them (thanks to SRP)

Before I encrypt the payload I generate a unique IV (nonce). After running the message through the cipher I have the encrypted message and a tag (message authentication code).

Therefore, the REST payload to the server roughly looks like:

{
  "kid": "LJNZZFQYWGTLBN4OROQ4J7GLBD",
  "enc": "AES-GCM",
  "iv": "AkR5QsOAwokwwopEBDDDjQ==", // base64
  "tag": "8ja1fhFeoUbgOmNzYV9zEQ==", // base64
  "data": "MIyMy3p3GIUZG6rJV3cZA7qXEcREIKumfAtT"
}

I am struggling to understand the benefit of sending the tag. Since we are using SRP the client and server are already using a unique (one-time) session key K.

Can't I just rely on the session key K to determine authenticity? That is, if the message is authentic, then I would be able to decrypt it using K and parse the JSON result into a valid value. (Note: In SRP the shared session key K is a symmetric key which can be used for encryption)

Further, would I send the tag in plaintext as listed above? Maybe asked differently, do I need to have any special handling of the tag when transmitting it to the server? (Is base64 a reasonable format?)

I am very green when it comes to cryptography (and trying to pick it up quickly). Any support appreciated.

$\endgroup$

1 Answer 1

1
$\begingroup$
  • Can't I just rely on the session key K to determine authenticity? That is, if the message is authentic, then I would be able to decrypt it using K and parse the JSON result into a valid value.*

Generally no. The authentication tag ensures that the message is encrypted properly for this particular key. GCM does not provide key commitment, so the message might also be valid for a different key (so the same message may authenticate two different users!). However, it should be impossible for an attacker to find a message that is valid for your current key - as long as you don't allow replay attacks.

GCM uses CTR as encryption mode. This mode XOR's a message with a generated key stream, created using the block cipher and a counter. It doesn't pad, and since any plaintext is valid, it will itself never find any error during decryption. Furthermore, it allows attackers to flip any bit, so if part of the message is known then an attacker can use that information to create any other message. For instance, it could flip only the values in a JSON message, leaving the JSON headers intact.

Further, would I send the tag in plaintext as listed above? Maybe asked differently, do I need to have any special handling of the tag when transmitting it to the server? (Is base64 a reasonable format?)

Yes, the tag can be "plaintext". The tag is binary. If you use a text interface such as JSON then base64 is reasonable yes (~33% overhead, easy conversion, well understood and usually available).


In your scheme it looks like "kid" identifies the key used. This might be dangerous considering that GCM doesn't commit to keys. Personally I'd be more happy with a HMAC computed value for entity authentication and a GCM with a derived key for message integrity / authentication. This will also allow you to distinguish between mangled messages and failed entity authentication more easily.

You might want to use / study TLS-SRP.

$\endgroup$
1
  • $\begingroup$ Thank you, that is more or less what was in my head, but good to hear someone else confirm it! As for the "kid", we are using stateless requests, so we have to have a way to "retrieve" the SRP state over multiple REST calls... But I'm actually work on a separate question about that so will link that here once ready. $\endgroup$
    – Joseph
    Commented Dec 3, 2022 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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