diff --git a/mRemoteNGTests/Security/AesGcmTests.cs b/mRemoteNGTests/Security/AesGcmTests.cs
new file mode 100644
index 000000000..bdf0dbe3c
--- /dev/null
+++ b/mRemoteNGTests/Security/AesGcmTests.cs
@@ -0,0 +1,54 @@
+using System.Security;
+using mRemoteNG.Security;
+using NUnit.Framework;
+
+
+namespace mRemoteNGTests.Security
+{
+ public class AesGcmTests
+ {
+ private SecureString _encryptionKey;
+ private string _plainText;
+
+ [SetUp]
+ public void Setup()
+ {
+ _encryptionKey = "mypassword111111".ConvertToSecureString();
+ _plainText = "MySecret!";
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ }
+
+ [Test]
+ public void GetBlockSizeReturnsProperValueForAes()
+ {
+ Assert.That(AESGCM.BlockSizeInBytes, Is.EqualTo(16));
+ }
+
+ [Test]
+ public void EncryptionOutputsBase64String()
+ {
+ var cipherText = AESGCM.Encrypt(_plainText, _encryptionKey);
+ Assert.That(cipherText.IsBase64String, Is.True);
+ }
+
+ [Test]
+ public void DecryptedTextIsEqualToOriginalPlainText()
+ {
+ var cipherText = AESGCM.Encrypt(_plainText, _encryptionKey);
+ var decryptedCipherText = AESGCM.Decrypt(cipherText, _encryptionKey);
+ Assert.That(decryptedCipherText, Is.EqualTo(_plainText));
+ }
+
+ [Test]
+ public void EncryptingTheSameValueReturnsNewCipherTextEachTime()
+ {
+ var cipherText1 = AESGCM.Encrypt(_plainText, _encryptionKey);
+ var cipherText2 = AESGCM.Encrypt(_plainText, _encryptionKey);
+ Assert.That(cipherText1, Is.Not.EqualTo(cipherText2));
+ }
+ }
+}
\ No newline at end of file
diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj
index 3a9fa4df5..95f866d73 100644
--- a/mRemoteNGTests/mRemoteNGTests.csproj
+++ b/mRemoteNGTests/mRemoteNGTests.csproj
@@ -105,6 +105,7 @@
+
Form
diff --git a/mRemoteV1/Security/AESGCM.cs b/mRemoteV1/Security/AESGCM.cs
index cc9ad4c64..57d995f5a 100644
--- a/mRemoteV1/Security/AESGCM.cs
+++ b/mRemoteV1/Security/AESGCM.cs
@@ -7,6 +7,7 @@
using System;
using System.IO;
+using System.Security;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
@@ -32,6 +33,8 @@ namespace mRemoteNG.Security
public static readonly int Iterations = 10000;
public static readonly int MinPasswordLength = 12;
+ public static int BlockSizeInBytes => 16;
+
///
/// Helper that generates a random new key on each call.
@@ -44,6 +47,18 @@ namespace mRemoteNG.Security
return key;
}
+ public static string Encrypt(string plainText, SecureString encryptionKey)
+ {
+ var encryptedText = SimpleEncryptWithPassword(plainText, encryptionKey.ConvertToUnsecureString());
+ return encryptedText;
+ }
+
+ public static string Decrypt(string cipherText, SecureString decryptionKey)
+ {
+ var decryptedText = SimpleDecryptWithPassword(cipherText, decryptionKey.ConvertToUnsecureString());
+ return decryptedText;
+ }
+
///
/// Simple Encryption And Authentication (AES-GCM) of a UTF8 string.
///
diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj
index 0c41b6e12..d24a6b7bd 100644
--- a/mRemoteV1/mRemoteV1.csproj
+++ b/mRemoteV1/mRemoteV1.csproj
@@ -168,6 +168,7 @@
+