94 lines
3.0 KiB
C#
94 lines
3.0 KiB
C#
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<AuthenticationTagMismatchException>());
|
|
}
|
|
|
|
[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<AuthenticationTagMismatchException>());
|
|
}
|
|
|
|
[Test]
|
|
public void Decrypt_RejectsWrongPurpose()
|
|
{
|
|
String encrypted = SacsAuthenticatedEncryption.Encrypt("Protected value", Key, Purpose);
|
|
|
|
Assert.That(
|
|
() => SacsAuthenticatedEncryption.Decrypt(encrypted, Key, "Tests:DifferentPurpose"),
|
|
Throws.TypeOf<AuthenticationTagMismatchException>());
|
|
}
|
|
|
|
[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<CryptographicException>());
|
|
}
|
|
|
|
[Test]
|
|
public void Encrypt_RejectsInvalidKeyLength()
|
|
{
|
|
Assert.That(
|
|
() => SacsAuthenticatedEncryption.Encrypt("value", new Byte[15], Purpose),
|
|
Throws.TypeOf<ArgumentException>());
|
|
}
|
|
|
|
// --- The End ---
|
|
}
|
|
}
|