Skip to main content
Bounty Ended with 50 reputation awarded by sribin
Add summary
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
  1. |Alice's ephemeral public key, Alice's static public key, Ciphertext, ECDSA's tag, MAC's tag| is wrong if we are making ECIES, as explained in 2. That should be [Alice's ephemeral public key || Ciphertext || HMAC's tag], per 5.1.3 Action 9 (with the necessary conversion from public key to bytestring implicit), yielding the output of ECIES, which is ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) of 1.

  2. I fail to parse "this is secure as sign-encrypt-sign". Leaving aside "secure as", it does not hold. With the changes indicated, it is made sign-then-encrypt, which is secure. Without the change, this is sort of encrypt-then-sign-plus-MAC-of-the-symmetric-part-of-the-ciphertext-and-include-that-in-the-MACed-data, the encryptionthis is not ECIES, and while I do not immediately see any attack, that's not a valid indication of security.

  3. "I am not sure that MAC's tag is necessary in this scheme": the MAC is necessary at least for the encryption to be what's named ECIES, and to benefit of its security argument. It also serves as a protection against poor implementations on the receiving side.

  4. In ECDSA's tag = ECDSA(Alice's public key || Ciphertext || Kmac, Alice's static private key), again I do not see why Alice's public key is part of what's signed; and Ciphertext is an internal variable of ECIES, which is dubious.

  5. It can be understoodA reading of the question is that an entityAlice reuses the same private key for ECDSA signature and ECIES decryption, which conceivably could have security implication. Formally, it makes ECIES's security argument invalid, and is explicitly against the ECDSA specification in FIPS 186-4:

Summary: The alternative proposed essentially replaces ECIES's MAC with an ECDSA signature (with ECIES's MAC key entering the data signed), and makes a number of other variations of the standard ECIES (at least, including the public key, and hashing the whole ephemeral public key rather than its $x$ coordinate). That's functionally encrypt-then-sign, with something that is not exactly ECIES and does not benefit from its security proof (though I see no attack). Beware however than any encrypt-then-sign reveals the identity of the signer, when the question started with the equation of sign-then-encrypt with ECIES, which demonstrably keeps the identity of the signer confidential until decryption. The question states that it performs sign-encrypt-sign, when it appears that it does not (unless Message is assumed to be M || ECDSA(Alice's static private key, M) ). The question does not state use of separate key pairs for signature and encryption, as required by standards and the security argument of ECDSA and ECIES.

  1. |Alice's ephemeral public key, Alice's static public key, Ciphertext, ECDSA's tag, MAC's tag| is wrong if we are making ECIES, as explained in 2. That should be [Alice's ephemeral public key || Ciphertext || HMAC's tag], per 5.1.3 Action 9 (with the necessary conversion from public key to bytestring implicit), yielding the output of ECIES, which is ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) of 1.

  2. I fail to parse "this is secure as sign-encrypt-sign". Leaving aside "secure as", it does not hold. With the changes indicated, it is made sign-then-encrypt, which is secure. Without the change, this is sort of encrypt-then-sign-plus-MAC-of-the-symmetric-part-of-the-ciphertext, the encryption is not ECIES, and while I do not immediately see any attack, that's not a valid indication of security.

  3. "I am not sure that MAC's tag is necessary in this scheme": the MAC is necessary at least for the encryption to be what's named ECIES, and to benefit of its security argument. It also serves as a protection against poor implementations on the receiving side

  4. In ECDSA's tag = ECDSA(Alice's public key || Ciphertext || Kmac, Alice's static private key), again I do not see why Alice's public key is part of what's signed; and Ciphertext is an internal variable of ECIES, which is dubious.

  5. It can be understood that an entity reuses the same private key for ECDSA signature and ECIES decryption, which conceivably could have security implication. Formally, it makes ECIES's security argument invalid, and is explicitly against the ECDSA specification in FIPS 186-4:

  1. |Alice's ephemeral public key, Alice's static public key, Ciphertext, ECDSA's tag, MAC's tag| is wrong if we are making ECIES, as explained in 2. That should be [Alice's ephemeral public key || Ciphertext || HMAC's tag], per 5.1.3 Action 9 (with the necessary conversion from public key to bytestring implicit), yielding the output of ECIES, which is ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) of 1.

  2. I fail to parse "this is secure as sign-encrypt-sign". Leaving aside "secure as", it does not hold. With the changes indicated, it is made sign-then-encrypt, which is secure. Without the change, this is encrypt-then-sign-the-symmetric-part-of-the-ciphertext-and-include-that-in-the-MACed-data, this is not ECIES, and while I do not immediately see any attack, that's not a valid indication of security.

  3. "I am not sure that MAC's tag is necessary in this scheme": the MAC is necessary at least for the encryption to be what's named ECIES, and to benefit of its security argument. It also serves as a protection against poor implementations on the receiving side.

  4. In ECDSA's tag = ECDSA(Alice's public key || Ciphertext || Kmac, Alice's static private key), again I do not see why Alice's public key is part of what's signed; and Ciphertext is an internal variable of ECIES, which is dubious.

  5. A reading of the question is that Alice reuses the same private key for ECDSA signature and ECIES decryption, which conceivably could have security implication. Formally, it makes ECIES's security argument invalid, and is explicitly against the ECDSA specification in FIPS 186-4:

Summary: The alternative proposed essentially replaces ECIES's MAC with an ECDSA signature (with ECIES's MAC key entering the data signed), and makes a number of other variations of the standard ECIES (at least, including the public key, and hashing the whole ephemeral public key rather than its $x$ coordinate). That's functionally encrypt-then-sign, with something that is not exactly ECIES and does not benefit from its security proof (though I see no attack). Beware however than any encrypt-then-sign reveals the identity of the signer, when the question started with the equation of sign-then-encrypt with ECIES, which demonstrably keeps the identity of the signer confidential until decryption. The question states that it performs sign-encrypt-sign, when it appears that it does not (unless Message is assumed to be M || ECDSA(Alice's static private key, M) ). The question does not state use of separate key pairs for signature and encryption, as required by standards and the security argument of ECDSA and ECIES.

Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
  1. ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) is sign-then-encrypt, which is perfectly fine. But count the signatures, there's only one (ECIES does not sign). Therefore this is not "sign-encrypt-sign" as described elsewhere.

  2. If we wanted to make sign-then-encrypt-then-sign, just replace the resulting ECIES result X by X || ECDSA(Alice's static private key, X). But take care that the final signature leaks who the signer is, when sign-then-encrypt keeps it confidential to all but the holder of the decryption private key.

  3. The "message for sending" is said to be [Alice's ephemeral public key, Alice's static public key, ciphertext, Mac's tag]. That's not matching the form of an ECIES cryptogram per SEC 1 Ver. 2.0, 5.1.3 Action 9, where Alice's static public key is not part of the output. Strictly stick to ECIES, or use another name. The ECIES result is [Alice's ephemeral public key || Ciphertext || Mac's tag]. If Alice's identity or public key or certificate is needed, it can be part of the message itself.

  4. What's hashed in Kenc || Kmac = KDF(SK) should be the (bytetring representation of the) $x$ coordinate of SK (per 5.1.3 Action 4), without the $y$ coordinate or parity bit. I would note Kenc || Kmac = KDF(SKx) to make the distinction explicit.

  5. In Ciphertext = Encrypt(Message, Kenc) it is not stated what Message is. If that's M, then M is not signed. That Message must be M || ECDSA(Alice's static private key, M) in order to match 1. It is critical that the ECDSA signature is encrypted, else confidentiality of the message is largely jeopardized (it becomes trivial to check a guess, e.g. of a coin toss, name, card number..)

  6. ECDSA's tag = ECDSA(Ciphertext, Alice static private key) comes as a surprise at this point, since Ciphertext is currently ECIES's internal symmetric ciphertext (denoted $EM$ in 5.1.3 Action 7), and not accessible externally from the ECIES black box. That makes reuse of proper ECIES code hairy: it's result must be parsed to extract the Ciphertext portion (as an aside, the question's notation is inconsistent on order of parameters, and use of possessive for asymmetric keys).

  7. HMAC's tag = MAC(Alice's static public key || Ciphertext || ECDSA's tag, Kmac) deviates from ECIES (5.1.3 Action 8). It should be replaced by HMAC's tag = MAC(Ciphertext, Kmac) (or HMAC's tag = MAC(Ciphertext || Sharedinfo2, Kmac) where Sharedinfo2 could be some externally agreed-upon bytestring; that could be Alice's static public key, but I do not see the point).

  8. The order is wrong in "Alice make ECDSA's tag first and after that make MAC's tag based on Alice's static public key, Ciphertext, and ECDSA's tag". For sign-then-encrypt that should be: Alice

  • Alice first makes ECDSA's signature/tag of M (this is typically first, but is independent of the next step and thus order is immaterial);
  • draws an ephemeral asymmetric key pair, multiplies Bob's public key by the ephemeral private key and forgets the later, extracts the $x$ coordinate of the result, derives from that the symmetric encryption and MAC keys used in the next two steps;
  • then symmetrically enciphers the concatenation of M and that signature/tag (with said concatenation denoted Message in the question), yielding ECIES's internal symmetric ciphertext (denoted Ciphertext in the question and $EM$ in 5.1.3 Action 7),;
  • then after that makemakes MAC's tag based on Ciphertext, and optionally Sharedinfo2;
  • then concatenateconcatenates the ephemeral asymmetric public key (which served as the source of the symmetric encryption and MAC keys), Ciphertext, and MAC (not the optional Sharedinfo2) into the ECIES result.
  1. ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) is sign-then-encrypt, which is perfectly fine. But count the signatures, there's only one (ECIES does not sign). Therefore this is not "sign-encrypt-sign" as described elsewhere.

  2. If we wanted to make sign-then-encrypt-then-sign, just replace the resulting ECIES result X by X || ECDSA(Alice's static private key, X). But take care that the final signature leaks who the signer is, when sign-then-encrypt keeps it confidential to all but the holder of the decryption private key.

  3. The "message for sending" is said to be [Alice's ephemeral public key, Alice's static public key, ciphertext, Mac's tag]. That's not matching the form of an ECIES cryptogram per SEC 1 Ver. 2.0, 5.1.3 Action 9, where Alice's static public key is not part of the output. Strictly stick to ECIES, or use another name. The ECIES result is [Alice's ephemeral public key || Ciphertext || Mac's tag]. If Alice's identity or public key or certificate is needed, it can be part of the message itself.

  4. What's hashed in Kenc || Kmac = KDF(SK) should be the (bytetring representation of the) $x$ coordinate of SK (per 5.1.3 Action 4), without the $y$ coordinate or parity bit. I would note Kenc || Kmac = KDF(SKx) to make the distinction explicit.

  5. In Ciphertext = Encrypt(Message, Kenc) it is not stated what Message is. If that's M, then M is not signed. That Message must be M || ECDSA(Alice's static private key, M) in order to match 1. It is critical that the ECDSA signature is encrypted, else confidentiality of the message is largely jeopardized (it becomes trivial to check a guess, e.g. of a coin toss, name, card number..)

  6. ECDSA's tag = ECDSA(Ciphertext, Alice static private key) comes as a surprise at this point, since Ciphertext is currently ECIES's internal symmetric ciphertext (denoted $EM$ in 5.1.3 Action 7), and not accessible externally from the ECIES black box. That makes reuse of proper ECIES code hairy: it's result must be parsed to extract the Ciphertext portion (as an aside, the question's notation is inconsistent on order of parameters, and use of possessive for asymmetric keys).

  7. HMAC's tag = MAC(Alice's static public key || Ciphertext || ECDSA's tag, Kmac) deviates from ECIES (5.1.3 Action 8). It should be replaced by HMAC's tag = MAC(Ciphertext, Kmac) (or HMAC's tag = MAC(Ciphertext || Sharedinfo2, Kmac) where Sharedinfo2 could be some externally agreed-upon bytestring; that could be Alice's static public key, but I do not see the point).

  8. The order is wrong in "Alice make ECDSA's tag first and after that make MAC's tag based on Alice's static public key, Ciphertext, and ECDSA's tag". For sign-then-encrypt that should be:

  • Alice first makes ECDSA's signature/tag of M,
  • then symmetrically enciphers the concatenation of M and that signature/tag (with said concatenation denoted Message in the question), yielding ECIES's internal symmetric ciphertext (denoted Ciphertext in the question and $EM$ in 5.1.3 Action 7),
  • then after that make MAC's tag based on Ciphertext, and optionally Sharedinfo2
  • then concatenate the ephemeral key (which served as the source of the symmetric encryption and MAC keys), Ciphertext, and MAC (not the optional Sharedinfo2) into the ECIES result.
  1. ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) is sign-then-encrypt, which is perfectly fine. But count the signatures, there's only one (ECIES does not sign). Therefore this is not "sign-encrypt-sign" as described elsewhere.

  2. If we wanted to make sign-then-encrypt-then-sign, just replace the resulting ECIES result X by X || ECDSA(Alice's static private key, X). But take care that the final signature leaks who the signer is, when sign-then-encrypt keeps it confidential to all but the holder of the decryption private key.

  3. The "message for sending" is said to be [Alice's ephemeral public key, Alice's static public key, ciphertext, Mac's tag]. That's not matching the form of an ECIES cryptogram per SEC 1 Ver. 2.0, 5.1.3 Action 9, where Alice's static public key is not part of the output. Strictly stick to ECIES, or use another name. The ECIES result is [Alice's ephemeral public key || Ciphertext || Mac's tag]. If Alice's identity or public key or certificate is needed, it can be part of the message itself.

  4. What's hashed in Kenc || Kmac = KDF(SK) should be the (bytetring representation of the) $x$ coordinate of SK (per 5.1.3 Action 4), without the $y$ coordinate or parity bit. I would note Kenc || Kmac = KDF(SKx) to make the distinction explicit.

  5. In Ciphertext = Encrypt(Message, Kenc) it is not stated what Message is. If that's M, then M is not signed. That Message must be M || ECDSA(Alice's static private key, M) in order to match 1. It is critical that the ECDSA signature is encrypted, else confidentiality of the message is largely jeopardized (it becomes trivial to check a guess, e.g. of a coin toss, name, card number..)

  6. ECDSA's tag = ECDSA(Ciphertext, Alice static private key) comes as a surprise at this point, since Ciphertext is currently ECIES's internal symmetric ciphertext (denoted $EM$ in 5.1.3 Action 7), and not accessible externally from the ECIES black box. That makes reuse of proper ECIES code hairy: it's result must be parsed to extract the Ciphertext portion (as an aside, the question's notation is inconsistent on order of parameters, and use of possessive for asymmetric keys).

  7. HMAC's tag = MAC(Alice's static public key || Ciphertext || ECDSA's tag, Kmac) deviates from ECIES (5.1.3 Action 8). It should be replaced by HMAC's tag = MAC(Ciphertext, Kmac) (or HMAC's tag = MAC(Ciphertext || Sharedinfo2, Kmac) where Sharedinfo2 could be some externally agreed-upon bytestring; that could be Alice's static public key, but I do not see the point).

  8. The order is wrong in "Alice make ECDSA's tag first and after that make MAC's tag based on Alice's static public key, Ciphertext, and ECDSA's tag". For sign-then-encrypt that should be: Alice

  • makes ECDSA's signature/tag of M (this is typically first, but is independent of the next step and thus order is immaterial);
  • draws an ephemeral asymmetric key pair, multiplies Bob's public key by the ephemeral private key and forgets the later, extracts the $x$ coordinate of the result, derives from that the symmetric encryption and MAC keys used in the next two steps;
  • then symmetrically enciphers the concatenation of M and that signature/tag (with said concatenation denoted Message in the question), yielding ECIES's internal symmetric ciphertext (denoted Ciphertext in the question and $EM$ in 5.1.3 Action 7);
  • then makes MAC's tag based on Ciphertext, and optionally Sharedinfo2;
  • then concatenates the ephemeral asymmetric public key, Ciphertext, and MAC (not the optional Sharedinfo2) into the ECIES result.
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
  • First decide if functionally the need is to have the signer's identity apparent to anyone by examination of the final cryptogram, or revealed only to the holder of the deciphering private key. For asymmetric/hybrid encryption and signature:
    • if the signer's identity is to be kept secret, or if in doubt, sign-then-encrypt;
    • if the signer's identity is to be apparent, encrypt-then-sign (sign-then-encrypt-then-sign also works here, but is not necessary for security when the next two recommendations are applied; it is however sometime justified, for example if cryptograms normally carrying the signer's ID must be transformable into anonymous ones by merely stripping the external signature, but should remain signed and non-repudiable after decryption).
  • In the above, encrypt should be precisely ECIES, including its ephemeral key generation, symmetric encryption, MAC, and concatenation to yield the result.
  • In the above, when using ECDSA, sign should be computing the ECDSA signature (including at least one hash step of the whole input) then adding the signature to the input (that can be either by appending or pretending it, as long as it can be unambiguously extracted on verification without risk of triggering implementation bugs).
  • If the identity, public key, or certificate of the sender needs to be included, add it immediately after or immediately before aperforming one signing step, or both (thator both); that can be either by appending or pretending itthe information, as long as it can be unambiguously extracted without risk of triggering implementation bugs).
  • When possible: one purpose, one key.
  • First decide if functionally the need is to have the signer's identity apparent to anyone by examination of the final cryptogram, or revealed only to the holder of the deciphering private key. For asymmetric/hybrid encryption and signature:
    • if the signer's identity is to be kept secret, or if in doubt, sign-then-encrypt;
    • if the signer's identity is to be apparent, encrypt-then-sign (sign-then-encrypt-then-sign also works here, but is not necessary for security when the next two recommendations are applied; it is however sometime justified, for example if cryptograms normally carrying the signer's ID must be transformable into anonymous ones by merely stripping the external signature, but should remain signed and non-repudiable after decryption).
  • In the above, encrypt should be precisely ECIES, including its ephemeral key generation, symmetric encryption, MAC, and concatenation to yield the result.
  • In the above, when using ECDSA, sign should be computing the ECDSA signature (including at least one hash step of the whole input) then adding the signature to the input (that can be either by appending or pretending it, as long as it can be unambiguously extracted on verification without risk of triggering implementation bugs).
  • If the identity, public key, or certificate of the sender needs to be included, add it immediately after or immediately before a signing step, or both (that can be either by appending or pretending it, as long as it can be unambiguously extracted without risk of triggering implementation bugs).
  • When possible: one purpose, one key.
  • First decide if functionally the need is to have the signer's identity apparent to anyone by examination of the final cryptogram, or revealed only to the holder of the deciphering private key. For asymmetric/hybrid encryption and signature:
    • if the signer's identity is to be kept secret, or if in doubt, sign-then-encrypt;
    • if the signer's identity is to be apparent, encrypt-then-sign (sign-then-encrypt-then-sign also works here, but is not necessary for security when the next two recommendations are applied; it is however sometime justified, for example if cryptograms normally carrying the signer's ID must be transformable into anonymous ones by merely stripping the external signature, but should remain signed and non-repudiable after decryption).
  • In the above, encrypt should be precisely ECIES, including its ephemeral key generation, symmetric encryption, MAC, and concatenation to yield the result.
  • In the above, when using ECDSA, sign should be computing the ECDSA signature (including at least one hash step of the whole input) then adding the signature to the input (that can be either by appending or pretending it, as long as it can be unambiguously extracted on verification without risk of triggering implementation bugs).
  • If the identity, public key, or certificate of the sender needs to be included, add it immediately after or immediately before performing one signing step (or both); that can be either by appending or pretending the information, as long as it can be unambiguously extracted without risk of triggering implementation bugs.
  • When possible: one purpose, one key.
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Polish
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading
Source Link
fgrieu
  • 145.6k
  • 12
  • 319
  • 611
Loading