public void AeadWithAdditionalDataTest()
        {
            var key = new byte[]
            {
                0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
                0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91,
                0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
                0x9b, 0x9c, 0x9d, 0x9e, 0x9f
            };

            var nonce = new byte[]
            {
                0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
                0x48, 0x49, 0x4a, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            };

            var ad = new byte[]
            {
                0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7
            };

            var m = Encoding.UTF8.GetBytes("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.");

            var encrypted = SecretAeadXChaCha20Poly1305.Encrypt(m, nonce, key, ad);
            var decrypted = SecretAeadXChaCha20Poly1305.Decrypt(encrypted, nonce, key, ad);

            CollectionAssert.AreEqual(m, decrypted);
        }
Example #2
0
        public void SecretAeadXChaCha20Poly1305EncryptWithBadAdditionalData()
        {
            var key = new byte[] {
                0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf,
                0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27,
                0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07
            };

            var nonce = new byte[] {
                0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a, 0x79, 0xc0, 0xd1, 0x10,
                0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a, 0x79, 0xc0, 0xd1, 0x10
            };

            var ad = new byte[] {
                0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0,
                0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0,
                0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0
            };

            var m = new byte[] {
                0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca
            };

            Assert.Throws <AdditionalDataOutOfRangeException>(
                () => SecretAeadXChaCha20Poly1305.Encrypt(m, nonce, key, ad));
        }
Example #3
0
 public static byte[] Decrypt(byte[] encryptedHeader, byte[] nonce, byte[] keyEncryptionKey, byte[] additionalData)
 {
     try
     {
         return(SecretAeadXChaCha20Poly1305.Decrypt(encryptedHeader, nonce, keyEncryptionKey, additionalData));
     }
     catch (CryptographicException)
     {
         return(null);
     }
 }
Example #4
0
        public void Decrypt_WithTestVectors_ExpectCorrectPlainText()
        {
            var expectedPlaintext = HexToBytes(PlaintextHex);
            var nonce             = HexToBytes(IvHex);
            var key = HexToBytes(KeyHex);
            var aad = HexToBytes(AadHex);

            var plaintext = BouncyDancing.Decrypt(key, nonce, testCiphertext, aad);

            plaintext.Should().BeEquivalentTo(expectedPlaintext);
            plaintext.Should().BeEquivalentTo(SecretAeadXChaCha20Poly1305.Decrypt(testCiphertext, nonce, key, aad));
        }
Example #5
0
        /// <summary>
        /// XChaCha20-Poly1305 in .NET using libsodium
        /// https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction
        /// </summary>
        public static void UsingLibsodium(byte[] key, byte[] nonce, byte[] plaintext)
        {
            // crypto_aead_xchacha20poly1305_ietf_encrypt
            var ciphertext = SecretAeadXChaCha20Poly1305.Encrypt(plaintext, nonce, key);

            Console.WriteLine($"Libsodium Ouput: {Convert.ToBase64String(ciphertext)}");

            // crypto_aead_xchacha20poly1305_ietf_decrypt
            var decyptedPlaintext = SecretAeadXChaCha20Poly1305.Decrypt(ciphertext, nonce, key);

            Console.WriteLine($"Libsodium Decrypted message: {Encoding.UTF8.GetString(decyptedPlaintext)}");
        }
Example #6
0
 public static byte[] Encrypt(byte[] passwordBytes, byte[] privateKey, byte[] keyAlgorithm)
 {
     byte[] salt = Generate.Salt();
     byte[] key  = Argon2.DeriveKey(passwordBytes, salt);
     Utilities.ZeroArray(passwordBytes);
     byte[] nonce              = Generate.Nonce();
     byte[] additionalData     = Utilities.ConcatArrays(keyAlgorithm, Constants.PrivateKeyVersion);
     byte[] keyCommitmentBlock = ChunkHandling.GetKeyCommitmentBlock();
     privateKey = Utilities.ConcatArrays(keyCommitmentBlock, privateKey);
     byte[] encryptedPrivateKey = SecretAeadXChaCha20Poly1305.Encrypt(privateKey, nonce, key, additionalData);
     Utilities.ZeroArray(privateKey);
     Utilities.ZeroArray(key);
     return(Utilities.ConcatArrays(additionalData, salt, nonce, encryptedPrivateKey));
 }
Example #7
0
        private static void Encrypt(FileStream inputFile, FileStream outputFile, byte[] nonce, byte[] dataEncryptionKey, byte[] additionalData)
        {
            const int offset = 0;

            byte[] plaintext = new byte[Constants.FileChunkSize];
            while (inputFile.Read(plaintext, offset, plaintext.Length) > 0)
            {
                byte[] plaintextChunk  = ChunkHandling.PrependKeyCommitmentBlock(plaintext);
                byte[] ciphertextChunk = SecretAeadXChaCha20Poly1305.Encrypt(plaintextChunk, nonce, dataEncryptionKey, additionalData);
                nonce          = Sodium.Utilities.Increment(nonce);
                additionalData = ChunkHandling.GetPreviousPoly1305Tag(ciphertextChunk);
                outputFile.Write(ciphertextChunk, offset, ciphertextChunk.Length);
            }
            Utilities.ZeroArray(dataEncryptionKey);
        }
Example #8
0
 private static byte[] Decrypt(byte[] passwordBytes, byte[] privateKey)
 {
     byte[] keyAlgorithm        = GetKeyAlgorithm(privateKey);
     byte[] keyVersion          = GetKeyVersion(privateKey);
     byte[] salt                = GetSalt(privateKey);
     byte[] nonce               = GetNonce(privateKey);
     byte[] additionalData      = Utilities.ConcatArrays(keyAlgorithm, keyVersion);
     byte[] encryptedPrivateKey = GetEncryptedPrivateKey(privateKey);
     byte[] key = Argon2.DeriveKey(passwordBytes, salt);
     Utilities.ZeroArray(passwordBytes);
     byte[] decryptedPrivateKey = SecretAeadXChaCha20Poly1305.Decrypt(encryptedPrivateKey, nonce, key, additionalData);
     Utilities.ZeroArray(key);
     ChunkHandling.ValidateKeyCommitmentBlock(decryptedPrivateKey);
     return(ChunkHandling.RemoveKeyCommitmentBlock(decryptedPrivateKey));
 }
Example #9
0
        private static void Decrypt(FileStream inputFile, FileStream outputFile, byte[] nonce, byte[] dataEncryptionKey, byte[] additionalData, int lastChunkLength)
        {
            int headersLength = FileHeaders.GetHeadersLength();

            inputFile.Seek(headersLength, SeekOrigin.Begin);
            const int offset = 0;

            byte[] ciphertextChunk = new byte[Constants.TotalChunkLength];
            while (inputFile.Read(ciphertextChunk, offset, ciphertextChunk.Length) > 0)
            {
                byte[] plaintextChunk = SecretAeadXChaCha20Poly1305.Decrypt(ciphertextChunk, nonce, dataEncryptionKey, additionalData);
                ChunkHandling.ValidateKeyCommitmentBlock(plaintextChunk);
                nonce          = Sodium.Utilities.Increment(nonce);
                additionalData = ChunkHandling.GetPreviousPoly1305Tag(ciphertextChunk);
                plaintextChunk = ChunkHandling.RemoveKeyCommitmentBlock(plaintextChunk);
                outputFile.Write(plaintextChunk, offset, plaintextChunk.Length);
            }
            outputFile.SetLength((outputFile.Length - Constants.FileChunkSize) + lastChunkLength);
            Utilities.ZeroArray(dataEncryptionKey);
        }
Example #10
0
 public static byte[] XChaCha20Encrypt(byte[] plaintext, byte[] nonce, byte[] key, byte[] assocData)
 {
     return(SecretAeadXChaCha20Poly1305.Encrypt(plaintext, nonce, key, assocData));
 }
Example #11
0
 public static byte[] XChaCha20Decrypt(byte[] ciphertext, byte[] nonce, byte[] key, byte[] assocData)
 {
     return(SecretAeadXChaCha20Poly1305.Decrypt(ciphertext, nonce, key, assocData));
 }
Example #12
0
 public static byte[] Encrypt(byte[] header, byte[] nonce, byte[] keyEncryptionKey, byte[] additionalData)
 {
     return(SecretAeadXChaCha20Poly1305.Encrypt(header, nonce, keyEncryptionKey, additionalData));
 }