3
$\begingroup$

I am using ECDSA P-384 for signing and verifying messages. The messages are basically stringified JSON. After receiving, the recipient verifies the signature using the public key.

Should the public key be included inside the message (aka the JSON which gets stringified)? Or should I send the public key separately along with the stringified JSON and the signature?

Does it make any difference?

The reason I ask is because if the public key is included inside the message (stringified JSON), then on the recipient side, first, I have to parse the JSON, then extract the public key, then do the verification. This seems a bit wasteful because if the signature failed, then the parsing of the stringified json was pointless.

Instead, if I simply included the public key separately along with the message and the signature of the message, then I won't have to parse the message first to extract the public key.

Another reason I ask is because the database stores the stringified json and also stores the parsed json along with another column for the public key. If the public key is part of the message, then it’s taking triple space because first it’s inside the stringified json column and then it’s also inside the parses json column along with in a separate column.

EDIT: I only want to ensure that the message itself hasn't been tampered with from the public key it's being sent by.

$\endgroup$
4
  • 1
    $\begingroup$ Either is fine. Some DSS similar to ECDSA actually does bind PK into the hash, e.g. Chinese SM2 digital signature. But from reading your question, the authentication of the peer public key seem to be entirely missing. $\endgroup$
    – DannyNiu
    Jun 27, 2023 at 3:35
  • $\begingroup$ @DannyNiu Sorry, what do you mean by "the authentication of the peer public key seem to be entirely missing"? If the recipient is receiving the public key, message and signature, and then verifying it using these, isn't that proof that the person who used their private key to sign the message actually did sign it? $\endgroup$ Jun 27, 2023 at 4:18
  • 2
    $\begingroup$ How do you know that public key corresponds to the private key of the entity you expect, and is not one generated by an attacker who substituted the public key in the JSON data and replaced the signature with one he faked with his private key? On the web, when we browse an HTTPS website, a CA signs a certificate asserting the public key of the website is authenticate, how do you achieve the same goal? $\endgroup$
    – DannyNiu
    Jun 27, 2023 at 4:26
  • $\begingroup$ @DannyNiu I don't need to know. I am only using it for verifying that the public key corresponds to the author and the signature matches. Basically, I want anyone to be able to submit messages. I only want to ensure that the message itself hasn't been tampered with. $\endgroup$ Jun 27, 2023 at 4:52

1 Answer 1

4
$\begingroup$

Leaving the JSON formatting aside, the question considers a server receiving public key $\mathrm{pk}$, an ECDSA signature $S$, and message $M$; and asks if the signature should be on $M$ or $\mathrm{pk}\|M$.

Contrary to standard practice, the server has no way to authenticate $\mathrm{pk}$; it only checks that $\mathrm{pk}$ is a valid ECDSA key, and that $\mathrm{pk}$ and $S$ verify against $M$ or $\mathrm{pk}\|M$, per ECDSA P-384.

The originally stated goal (in this comment) was:

I only want to ensure that the message itself hasn't been tampered with.

This goal is not and can't be met under the standard assumption in crypto when it comes to message tampering: an active malicious adversary. There's nothing to stop the message from being extracted, modified, resigned with a new private key $\mathrm{sk'}$, which matching new public key $\mathrm{pk'}$ replaces $\mathrm{pk}$.

The updated goal is:

I only want to ensure that the message itself hasn't been tampered with from the public key it's being sent by.

Reading this as "…hasn't been tampered with compared to when it was signed with the private key matching the public key it's received with", that goal is met with both signing methods (under the standard assumption that ECDSA P-384 is EUF-CMA secure):

Some other goals are met too (under further standard assumptions that whoever generates the $\mathrm{sk}/\mathrm{pk}$ key pair does so securely and does not let $\mathrm{sk}$ leak, and uses it only for the purpose of signing messages as prescribed):

  • The server can be convinced that $\mathrm{pk}\mathbin\|S\mathbin\|M$ and $\mathrm{pk}\mathbin\|S'\mathbin\|M'$ that both verify are signed by the same signer, and that neither $M$ nor $M'$ are altered compared to what that signer signed.
  • A party knowing $\mathrm{sk}$ matching $\mathrm{pk}$ can convince the server that it knew $M$ when the server received $\mathrm{pk}\mathbin\|S\mathbin\|M$ that verifies.

Towards the above goals (and under the standard assumption that the hash used in ECDSA is secure), I do not see a security advantage to the more complex option of signing $\mathrm{pk}\|M$.

If the public/private key pair $\mathrm{pk}/\mathrm{sk}$ is used for multiple purposes (against the "one usage, one key" principle), and if the server's protocol is the only of these purposes such that $\mathrm{pk}$ could appear at start of what's signed, then signing $\mathrm{pk}\|M$ has the beneficial side effect that it's impossible to misuse a signature produced for another usage towards impersonating the holder of the key pair on the server. However, the convention of signing $\mathrm{Prefix}\|M$ where $\mathrm{Prefix}$ is unique to each usage is a cleaner way to achieve the same goal.

There are some other thin security advantages; like: advance knowledge of the hash of $M$ can't help an adversary misappropriate a message $M$ that it does not yet know in entirety. If only $M$ is signed, such attack is possible by altering the beginning of $\mathrm{pk}\mathbin\|S\mathbin\|M$.

Looking at the attacks in Dennis Jackson, Cas Cremers, Katriel Cohn-Gordon, and Ralf Sasse's Seems Legit: Automated Analysis of Subtle Attacks on Protocols that Use Signatures, I do not see that they would be a concern in the context, and further:

  • ECDSA with fixed curve (as in the question) is secure against SEO/DEO attacks that misappropriate a signature (signing $\mathrm{pk}\|M$ thwarts that, including when the curve is a parameter of the public key).
  • ECDSA signatures are malleable (ECDSA is not sEUF-CMA), but that's regardless of what's hashed.

Signing $\mathrm{pk}\|M$ has a functional disadvantage beside what the question lists: if the server de-duplicates large messages sent by multiple users, then the server has to hash the whole message once more for each signature verified.

$\endgroup$
4
  • $\begingroup$ I only want to ensure that the message itself hasn't been tampered with from the public key it's being sent by. Regarding "There's nothing to stop the message from being extracted, modified, and resigned with a new private key." This would fail verification against the original public key though no? Because the message is modified plus also signed with a new private key, the original public key would not longer be able to verify this modified message to match the original signature. So, such message tampering will be detected by the recipient due to failure or verification. Am I wrong? $\endgroup$ Jun 27, 2023 at 9:30
  • 1
    $\begingroup$ @sudoExclaimationExclaimation: Since you describe no way by which the "recipient" would know the original public key, or otherwise detect that the new public key (matching the new private key) is not the original public key, we must conclude the "recipient" would not detect the tampering of the message. $\endgroup$
    – fgrieu
    Jun 27, 2023 at 11:24
  • $\begingroup$ I only want to detect "tampering" to the extent that the public key which is provided with the message & signature all work together. On the recipient server side, it doesn't care about who it came from. Only cares about whether the public key being provided verifies the signature. If yes, then it stores it for that public key. Even if someone took the original message, modified it, then signed with a new private key, recipient server will merely store it as being authored by a different person than the original person. $\endgroup$ Jun 27, 2023 at 19:37
  • $\begingroup$ I am implementing something similar to NOSTR: github.com/nostr-protocol/nips/blob/master/01.md $\endgroup$ Jun 27, 2023 at 19:37

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.