using System; using System.Security.Cryptography; using NUnit.Framework; using Sarand.Net.Standard.Base.Helpers; namespace Sacs.UnitTests.Net.Standard.Base.Helpers { [TestFixture] public class SacsAuthenticatedEncryption_Tester { // --- Data Members --- private static readonly Byte[] Key = Convert.FromHexString("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); private const String Purpose = "Tests:AuthenticatedEnvelope"; // --- Tests --- [TestCase("")] [TestCase("Plain ASCII text")] [TestCase("Unicode £ € 漢字 and emoji 😀")] public void EncryptDecrypt_RoundTrips(String value) { String encrypted = SacsAuthenticatedEncryption.Encrypt(value, Key, Purpose); Assert.That(encrypted, Does.StartWith(SacsAuthenticatedEncryption.EnvelopePrefix)); Assert.That(encrypted, Does.Not.Contain("+").And.Not.Contain("/").And.Not.EndWith("=")); Assert.That(SacsAuthenticatedEncryption.Decrypt(encrypted, Key, Purpose), Is.EqualTo(value)); } [Test] public void Encrypt_UsesUniqueNonces() { String first = SacsAuthenticatedEncryption.Encrypt("Repeated value", Key, Purpose); String second = SacsAuthenticatedEncryption.Encrypt("Repeated value", Key, Purpose); Assert.That(second, Is.Not.EqualTo(first)); } [Test] public void Decrypt_RejectsModifiedEnvelope() { String encrypted = SacsAuthenticatedEncryption.Encrypt("Protected value", Key, Purpose); Int32 modifiedIndex = SacsAuthenticatedEncryption.EnvelopePrefix.Length; Char replacement = encrypted[modifiedIndex] == 'A' ? 'B' : 'A'; String modified = encrypted.Substring(0, modifiedIndex) + replacement + encrypted.Substring(modifiedIndex + 1); Assert.That( () => SacsAuthenticatedEncryption.Decrypt(modified, Key, Purpose), Throws.TypeOf()); } [Test] public void Decrypt_RejectsWrongKey() { String encrypted = SacsAuthenticatedEncryption.Encrypt("Protected value", Key, Purpose); Byte[] wrongKey = Convert.FromHexString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); Assert.That( () => SacsAuthenticatedEncryption.Decrypt(encrypted, wrongKey, Purpose), Throws.TypeOf()); } [Test] public void Decrypt_RejectsWrongPurpose() { String encrypted = SacsAuthenticatedEncryption.Encrypt("Protected value", Key, Purpose); Assert.That( () => SacsAuthenticatedEncryption.Decrypt(encrypted, Key, "Tests:DifferentPurpose"), Throws.TypeOf()); } [TestCase("legacy-ciphertext")] [TestCase("SACSENC2.not-valid-base64!")] [TestCase("SACSENC2.AA")] public void Decrypt_RejectsUnsupportedOrMalformedValues(String value) { Assert.That( () => SacsAuthenticatedEncryption.Decrypt(value, Key, Purpose), Throws.TypeOf()); } [Test] public void Encrypt_RejectsInvalidKeyLength() { Assert.That( () => SacsAuthenticatedEncryption.Encrypt("value", new Byte[15], Purpose), Throws.TypeOf()); } // --- The End --- } }