question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

What it means in practice: "Using the same nonce with the same key more than once leads to catastrophic loss of security."

See original GitHub issue

Hello,

It’s is not an issue per si, but, this repo does not have Discussions tab enabled.


I’m try using the AeadAlgorithm.XChaCha20Poly1305, and I little bit confused when read:

Note

Using the same nonce with the same key more than once leads to catastrophic loss of security.

To prevent nonce reuse when encrypting multiple plaintexts with the same key, it is recommended to increment the previous nonce; a randomly generated nonce is not suitable.

In my scenario I need to encrypt some data and decrypt this data in another moment, like an Token:

>. Request: `my-web-api/token/generate`
>. Response: Some `ciphertext` generated by `XChaCha20Poly1305` in `Base64` format.

But when I tried to use the recommended practices in nonce value(increment) I can’t Decrypt data. In my thinking I need the suitable nonce to do the correct data decryption, but, how will I know the appropriate one, if I auto-incremented the value? I need always extern/public the nonce I used? Like:

“Encrypt”

>. Request: `my-web-api/token/generate`
>. Response: Some `ciphertext` generated by `XChaCha20Poly1305` in `Base64` format + `nonce`.

“Decrypt”

>. Request: `my-web-api/token/validate`
>. Body: `ciphertext` in `Base64` format with `nonce`.

Some foo code example:

class Program
    {
        public static byte[] ExportedKey;
        
        static void Main(string[] args)
        {
            const string json =
                @"{'Id':'62fea73265676bb8c06749a7','TriadKey':'111155555555555555555555555555555555555555555151513321321321654654654897897654654321321112','IsValid':false,'ExpirationDate':'2022-08-19T20:55:14.6146798Z'}";

            Aes256Gcm(AeadAlgorithm.Aes256Gcm, "Z8c0kX9ATszSsKCAROHnZw==", json);
            
            Console.ReadLine();
        }

        private static void Aes256Gcm(AeadAlgorithm aeadAlgorithm, string nonceText, string dataText)
        {
            // create a new key pair
            var creationParameters = new KeyCreationParameters
            {
                ExportPolicy = KeyExportPolicies.AllowPlaintextArchiving
            };
            
            using var key = Key.Create(aeadAlgorithm, creationParameters);
            ExportedKey = key.Export(KeyBlobFormat.NSecSymmetricKey);
            File.WriteAllBytes("private-secret-key.nsec", ExportedKey);
        
            // generate some data to be signed
            var data = Encoding.UTF8.GetBytes(dataText);
            var nonce = Encoding.UTF8.GetBytes(nonceText);
            // increment nonce
            nonce[0]++;

            // sign the data using the private key
            var ciphertext = aeadAlgorithm.Encrypt(key: key, nonce: nonce, plaintext: data, associatedData: null);
            Console.WriteLine($"Encrypted Data:\n{Convert.ToBase64String(ciphertext)}\n");
            
            // DUMB: simulates "new request" `my-web-api/token/validate` = NEW NONCE/INCREMENTED
            nonce[0]++;
            
            Decrypt(aeadAlgorithm, nonce, ciphertext);
        }

        private static void Decrypt(AeadAlgorithm aeadAlgorithm, byte[] nonce, byte[] ciphertext)
        {
            // re-import it
            using var key = Key.Import(aeadAlgorithm, ExportedKey, KeyBlobFormat.NSecSymmetricKey);
            
            var decryptedPlaintext = aeadAlgorithm.Decrypt(key, nonce, default, ciphertext);

            Console.WriteLine
            (
                decryptedPlaintext is null
                    ? "Data decryption failed."
                    : $"Decrypted Data:\n{Encoding.UTF8.GetString(decryptedPlaintext)}\n"
            );
        }
    }

OUTPUT: “Data decryption failed.” - Because use different nouce

What would be the proper way to deal with this scenario?

Cheers! 😁

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
igorgomeslimacommented, Sep 27, 2022
1reaction
samuel-lucas6commented, Aug 31, 2022

You refer this part of code?

@igorgomeslima Yes, you could prepend the nonce to the ciphertext (e.g. using Array.Copy(), the LINQ .Concat(), etc) before converting the whole thing to a Base64 string. Then you convert the Base64 to a byte array and retrieve the nonce as bytes from the beginning.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AES use same Nonce security risk?
When using AES-GCM, using the same nonce and key pair for multiple messages is catastrophic. You lose all of the security guarantees AES...
Read more >
Introducing Miscreant: a multi-language misuse resistant ...
Repeated use of the same nonce under the same key causes most ciphers to fail catastrophically, as we just saw with the recent...
Read more >
RFC 8452: AES-GCM-SIV: Nonce Misuse-Resistant ...
For up to 256 uses of the same nonce and key (i.e., where one can assume that nonce misuse is no more than...
Read more >
Nonce reuse for different recipients? - cryptography
You're right that reusing a nonce with the same key would result in a catastrophic loss of privacy with a stream cipher like...
Read more >
KRACK Attacks: Breaking WPA2
This website presents the Key Reinstallation Attack (KRACK). It breaks the WPA2 protocol by forcing nonce reuse in encryption algorithms used by Wi-Fi....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found