Warding an ECIES setup against MitM: ECDSA? Is it necessary/appropriate to digitally sign an ETM file in an ECIES context? The encryption mode is CTR(using Inferno). The current output is:

[shared public key] [ciphertext] [MAC].

The encrypted files travel through email between users, if it matters.

The users need to make sure the messages they receive come from the expected person, and none of them is willing to trust a CA. Would it make sense to sign the files with ECDSA?

Here is the application's current code(C#) used for encryption, decryption and authentication, using Inferno(without ECDSA):

    internal static void Encrypt(CngKey k, string file, object data)
    {
        var ephemeralBundle = k.GetSharedEphemeralDhmSecret();
        var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
        var symmetricKey = ephemeralBundle.SharedSecret;                                               

        using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
        {
            fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
            using (var etm = new EtM_EncryptTransform(symmetricKey))
            using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))
                new BinaryFormatter().Serialize(cs, data);                                    
        }
    }

    internal static object Decrypt(string file, CngKey k)
    {
        object decrypted = null;
        var ephemeralPublic = new byte[104];

        using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
        {
            fs.Read(ephemeralPublic, 0, 104);
            var ephemeralSymmetric = k.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
            if (Authenticate(file, ephemeralSymmetric, 104))
            {
                using (var etm = new EtM_DecryptTransform(ephemeralSymmetric))
                using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
                    decrypted = new BinaryFormatter().Deserialize(cs);                    
            }
        }
        return decrypted;
    }

    private static bool Authenticate(string file, byte[] key, int offset)
    {
        using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
        using (var etm = new EtM_DecryptTransform(key, authenticateOnly: true))
        {
            fs.Position = offset;
            using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read)) cs.CopyTo(Stream.Null);
            if (!etm.IsComplete) throw new Exception("Authentication failed.");
        }
        return true;
    }
Yes, if you want to protect the message you could use sign-then-encrypt or sign-then-encrypt-then sign to provide authenticity and integrity. Without it an attacker may change the bits of the ciphertext, or simply create an encrypted message.

ECDSA would be the logical choice if you're already using ECIES. It may still be a good idea to use separate keys for signing and encrypting though (if just because you need the keys on different occasions).



You need to trust the public key of the other person before signing or encryption makes any sense though. It's OK not to trust a CA, but in that case you need a different way of performing key management within your PKI.

You could use separate channels to confirm key fingerprints, you could use a web-of-trust, share keys by sneakernet (memory sticks) whatever. But if eavesdropping is possible then 9 times out of 10 so are MitM, so you should make sure that an attacker cannot substitute the public key with their own public key.