0
$\begingroup$

I'm coding(in C#) an offline(no network or server), hybrid file encryption app, implementing Inferno's ECIES. The user's private key is to be stored either on the pc drive or on a usb key, after being encrypted with a key(password) hashed with ~ 1 million Scrypt iterations. The user can load his key into protected memory once the app is started. Loading the key takes a huge 20 seconds but it would be a one-time/session delay if the following is acceptable:

For files meant to be kept by the user(some are sent, some are kept), is it secure to produce a "shared" symmetric key with the user's own public key? This would allow the user to have one password to remember(instead of one for each symmetric and asymmetric key) and since the symmetric key produced this way has a high entropy, hashing iterations are not necessary when saving/loading files, something that happens very often during a session.

The code itself is working but that does not tell me if the approach is secure. Just to make sure I'm clear, here is a shortened code example:

    internal static void SendText(string text, byte[] ephemeralPublicBlob, string file)
    {
        CngKey receiverKey = ephemeralPublicBlob.ToPublicKeyFromBlob();            
        var ephemeralBundle = receiverKey.GetSharedEphemeralDhmSecret();            
        var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;            
        var ephemeralSymmetric = ephemeralBundle.SharedSecret;            
        var textSegment = new ArraySegment<byte>(text.ToBytes());
        var ciphertext = SuiteB.Encrypt(ephemeralSymmetric, textSegment);            

        using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
        {
            byte[] sent = Utils.Combine(ephemeralPublic, ciphertext);
            fs.Write(sent, 0, sent.Length);
        }
    }

    internal static string ReceiveText(string file, CngKey masterKey)
    {
        string decrypted = null;
        using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
        {
            byte[] received = new byte[fs.Length];
            fs.Read(received, 0, (int)fs.Length);
            var ephemeralPublic = new ArraySegment<byte>(received, 0, 104);
            var cipherText = new ArraySegment<byte>(received, 104, received.Length - 104);                
            var sharedSecret = masterKey.GetSharedDhmSecret(ephemeralPublic.ToArray().ToPublicKeyFromBlob());
            decrypted = SuiteB.Decrypt(sharedSecret, cipherText).FromBytes();                
        }
        return decrypted;
    }  

So, in the first function(SendText), if I pass the sender's(instead of receiver's) public blob as the byte[] argument, the code works, but am I leaking/messing something?

$\endgroup$

closed as off-topic by e-sushi Dec 4 '16 at 20:52

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Programming questions are off-topic even if you are writing or debugging cryptographic code. Unless your question is specifically about how the cryptographic algorithm or protocol works, you should look into asking on Stack Overflow instead." – e-sushi
If this question can be reworded to fit the rules in the help center, please edit the question.

0
$\begingroup$

You are not leaking anything, because ephemeralBundle will contain a new, unique public-private ephemeral key pair, and the encryption will occur with brand-new [ephemeral_public sender_private == ephemeral_private sender_public] secret key.

Using sender's pk as a receiver (ie. sending to yourself) is safe in your scenario above.

$\endgroup$

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