94 lines
2.9 KiB
C#
94 lines
2.9 KiB
C#
using System;
|
|
using NUnit.Framework;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using Sarand.Net.Standard.Base.Data;
|
|
using Sarand.Net.Standard.Base.Helpers;
|
|
|
|
namespace Sacs.UnitTests.Net.Standard.Base.Data
|
|
{
|
|
[TestFixture]
|
|
public class SacsAesGcmCrypter_Tester
|
|
{
|
|
// --- Data Members ---
|
|
|
|
private static readonly Random random = new Random(11437);
|
|
|
|
// --- Tests ---
|
|
|
|
[Test]
|
|
public void EncryptDecrypt_RoundTripsRandomText()
|
|
{
|
|
const String purpose = "Tests:SacsAesGcmCrypter";
|
|
for (int i = 0; i < 200; i++)
|
|
{
|
|
String data = RandomString(random.Next(10, 2048), true);
|
|
String key = RandomString(random.Next(10, 128), true);
|
|
String encrypted = SacsAesGcmCrypter.Encrypt(data, key, purpose);
|
|
|
|
Assert.That(SacsAesGcmCrypter.Decrypt(encrypted, key, purpose), Is.EqualTo(data));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Decrypt_RejectsLegacyCiphertext()
|
|
{
|
|
const String encrypted = "0qlOvuM3L9+yzc6XnuHSv2Jq/1v1pyPq6CaCYnMauW6n+bBc9YOBNPtaNFm+2JGz;zgCog0OpwdN+I8yK5UAU8g==";
|
|
const String key = "Compatibility-Key-2026!";
|
|
|
|
Assert.That(
|
|
() => SacsAesGcmCrypter.Decrypt(encrypted, key, "Tests:SacsAesGcmCrypter"),
|
|
Throws.TypeOf<CryptographicException>());
|
|
}
|
|
|
|
[Test]
|
|
public void Decrypt_RejectsUnencryptedText()
|
|
{
|
|
const String value = "A value without an appended IV";
|
|
|
|
Assert.That(
|
|
() => SacsAesGcmCrypter.Decrypt(value, "unused-key", "Tests:SacsAesGcmCrypter"),
|
|
Throws.TypeOf<CryptographicException>());
|
|
}
|
|
|
|
[Test]
|
|
public void Encrypt_UsesUniqueNonces()
|
|
{
|
|
const String value = "Repeated value";
|
|
const String key = "Repeated-key";
|
|
const String purpose = "Tests:SacsAesGcmCrypter";
|
|
|
|
String first = SacsAesGcmCrypter.Encrypt(value, key, purpose);
|
|
String second = SacsAesGcmCrypter.Encrypt(value, key, purpose);
|
|
|
|
Assert.That(first, Is.Not.EqualTo(second));
|
|
Assert.That(first, Does.StartWith(SacsAuthenticatedEncryption.EnvelopePrefix));
|
|
Assert.That(SacsAesGcmCrypter.Decrypt(first, key, purpose), Is.EqualTo(value));
|
|
Assert.That(SacsAesGcmCrypter.Decrypt(second, key, purpose), Is.EqualTo(value));
|
|
}
|
|
|
|
[Test]
|
|
public void Decrypt_RejectsWrongPurpose()
|
|
{
|
|
String encrypted = SacsAesGcmCrypter.Encrypt("Purpose-bound", "purpose-key", "Tests:FirstPurpose");
|
|
|
|
Assert.That(
|
|
() => SacsAesGcmCrypter.Decrypt(encrypted, "purpose-key", "Tests:SecondPurpose"),
|
|
Throws.TypeOf<AuthenticationTagMismatchException>());
|
|
}
|
|
|
|
// --- Utilities ---
|
|
|
|
/// <summary>Generate random alphanumeric string</summary>
|
|
private static String RandomString(int length, bool includeLowerCase = true, bool includeSymbols = true)
|
|
{
|
|
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
if (includeLowerCase) chars += "abcdefghijklmnopqrstuvwxyz";
|
|
if (includeSymbols) chars += "`¬!\"£$%^&*()-=_+{}[];:'@#~<>?/.,\\| ";
|
|
return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
|
}
|
|
|
|
// --- The End ---
|
|
}
|
|
}
|