public void VerifyLibhydrogenEncryptedMessageCanBeDecrypted()
        {
            var sb = new SecretBox();

            // Generate a key
            var key = new byte[SecretBox.KeyBytes];

            sb.GenerateKey(key);

            // Generate a message to encrypt
            var          message   = Encoding.UTF8.GetBytes("You are old Father William, the young man said");
            const int    messageId = 1;
            const string context   = "test";

            // Buffer to hold the ciphertext
            var ciphertext = new byte[sb.CalculateCiphertextLength(message.Length)];

            // Encrypt using libhydrogen
            var result = hydro_secretbox_encrypt(
                ciphertext, message, message.Length, messageId, context, key);

            // Verify that some ciphertext was generated
            Assert.That(ciphertext, Is.Not.All.Zero);
            Assert.That(result, Is.EqualTo(0));

            // Decrypt using SecretBox
            var decryptedMessage = new byte[message.Length];

            sb.Decrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId);

            // Verify the decrypt was successful
            Assert.That(decryptedMessage, Is.EqualTo(message));
        }
예제 #2
0
        public void CalculateCipherTextLength()
        {
            const int messageLength  = 10;
            const int expectedLength = messageLength + HeaderBytes;
            var       sb             = new SecretBox();

            Assert.That(sb.CalculateCiphertextLength(messageLength), Is.EqualTo(expectedLength));
        }
예제 #3
0
        public void VerifyDecryptFailsWithInvalidParameters()
        {
            // Encrypt a message
            var sb  = new SecretBox();
            var key = new byte[KeyBytes];

            sb.GenerateKey(key);
            var          message    = Encoding.UTF8.GetBytes("You are old Father William, the young man said");
            const int    messageId  = 1;
            const string context    = "test";
            var          ciphertext = new byte[sb.CalculateCiphertextLength(message.Length)];

            sb.Encrypt(ciphertext, message, message.Length, key, context, messageId);

            // Buffer to hold decrypted message
            var decryptedMessage = new byte[message.Length];

            // CiphertextLength is incorrect
            Assert.That(
                () => sb.Decrypt(decryptedMessage, ciphertext, HeaderBytes, key, context, messageId),
                Throws.TypeOf <CryptographicException>().With.Message.EqualTo("MAC check failed"));
            Assert.That(
                sb.TryDecrypt(decryptedMessage, ciphertext, HeaderBytes, key, context, messageId),
                Is.False);

            // MessageId is incorrect
            Assert.That(
                () => sb.Decrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, 2),
                Throws.TypeOf <CryptographicException>().With.Message.EqualTo("MAC check failed"));

            // Verify the decrypted message is not equal to the message, as a failed MAC check should not
            // leak the plaintext
            Assert.That(decryptedMessage, Is.Not.EqualTo(message));

            Assert.That(
                sb.TryDecrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, 2),
                Is.False);
            Assert.That(decryptedMessage, Is.Not.EqualTo(message));

            // Key is invalid
            key[0]++;
            Assert.That(
                () => sb.Decrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId),
                Throws.TypeOf <CryptographicException>().With.Message.EqualTo("MAC check failed"));
            Assert.That(
                sb.TryDecrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId),
                Is.False);
            key[0]--;

            // Ciphertext is invalid
            ciphertext[12]++;
            Assert.That(
                () => sb.Decrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId),
                Throws.TypeOf <CryptographicException>().With.Message.EqualTo("MAC check failed"));
            Assert.That(
                sb.TryDecrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId),
                Is.False);
        }
예제 #4
0
        public void CalculateCipherTextLength_LessThanZero()
        {
            var sb = new SecretBox();

            Assert.That(
                () => sb.CalculateCiphertextLength(-3),
                Throws.ArgumentException.With.Message.EqualTo(
                    "messageLength must be greater than 0"));
        }
예제 #5
0
        public void Encrypt_ValidateContextLength_TooLong()
        {
            var       sb   = new SecretBox();
            var       key  = new byte[KeyBytes];
            const int mlen = 12;
            var       m    = new byte[mlen];
            var       c    = new byte[sb.CalculateCiphertextLength(mlen)];
            var       ctx  = "you are old father william";

            Assert.That(
                () => sb.Encrypt(c, m, mlen, key, ctx),
                Throws.ArgumentException.With.Message.EqualTo(
                    $"'context' must be at most {ContextBytes} characters"));
        }
예제 #6
0
        public void Encrypt_ValidateKeyLength(int keyLength)
        {
            var       sb   = new SecretBox();
            var       key  = new byte[keyLength];
            const int mlen = 12;
            var       m    = new byte[mlen];
            var       c    = new byte[sb.CalculateCiphertextLength(mlen)];
            var       ctx  = "test";

            Assert.That(
                () => sb.Encrypt(c, m, mlen, key, ctx),
                Throws.ArgumentException.With.Message.EqualTo(
                    $"'key' length must be {KeyBytes} bytes"));
        }
예제 #7
0
        public void Encrypt_ValidateMessageLength_TooLong()
        {
            var       sb         = new SecretBox();
            var       key        = new byte[KeyBytes];
            const int mlen       = 44;
            const int mlenActual = 12;
            var       m          = new byte[mlenActual];
            var       c          = new byte[sb.CalculateCiphertextLength(mlenActual)];
            var       ctx        = "test";

            Assert.That(
                () => sb.Encrypt(c, m, mlen, key, ctx),
                Throws.ArgumentException.With.Message.EqualTo(
                    $"'messageLength' must be at most the length of 'message'"));
        }
예제 #8
0
        public void VerifyMessageCanBeEncryptedAndDecrypted()
        {
            var sb = new SecretBox();

            // Generate a key
            var key = new byte[KeyBytes];

            sb.GenerateKey(key);

            // Generate a message to encrypt
            var          message   = Encoding.UTF8.GetBytes("You are old Father William, the young man said");
            const int    messageId = 1;
            const string context   = "test";

            // Buffer to hold the ciphertext
            var ciphertext = new byte[sb.CalculateCiphertextLength(message.Length)];

            // Encrypt
            sb.Encrypt(ciphertext, message, message.Length, key, context, messageId);

            // Buffer to hold decrypted message
            var decryptedMessage = new byte[message.Length];

            // Decrypt
            sb.Decrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId);

            // Verify the decrypted message
            Assert.That(decryptedMessage, Is.EqualTo(message));

            // Decrypt using TryDecrypt
            Array.Clear(decryptedMessage, 0, decryptedMessage.Length);
            var result = sb.TryDecrypt(decryptedMessage, ciphertext, ciphertext.Length, key, context, messageId);

            // Verify the decrypted message
            Assert.That(decryptedMessage, Is.EqualTo(message));
            Assert.That(result, Is.True);
        }