mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-26 12:08:37 +08:00
Modified AESGCM to support specifying the block cipher engine through generics
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Security;
|
||||
using mRemoteNG.Security;
|
||||
using NUnit.Framework;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
|
||||
namespace mRemoteNGTests.Security
|
||||
@@ -14,7 +15,7 @@ namespace mRemoteNGTests.Security
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_aesgcm = new AESGCM();
|
||||
_aesgcm = new AESGCM<AesFastEngine>();
|
||||
_encryptionKey = "mypassword111111".ConvertToSecureString();
|
||||
_plainText = "MySecret!";
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ using System.IO;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Engines;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Crypto.Modes;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
@@ -18,9 +17,11 @@ using Org.BouncyCastle.Security;
|
||||
|
||||
namespace mRemoteNG.Security
|
||||
{
|
||||
|
||||
public class AESGCM : ICryptographyProvider
|
||||
public class AESGCM<TBlockCipher> : ICryptographyProvider
|
||||
where TBlockCipher : IBlockCipher, new()
|
||||
{
|
||||
private readonly IBlockCipher _blockCipher;
|
||||
private IAeadBlockCipher _aeadBlockCipher;
|
||||
private readonly SecureRandom Random = new SecureRandom();
|
||||
|
||||
//Preconfigured Encryption Parameters
|
||||
@@ -33,20 +34,15 @@ namespace mRemoteNG.Security
|
||||
public readonly int Iterations = 10000;
|
||||
public readonly int MinPasswordLength = 12;
|
||||
|
||||
public int BlockSizeInBytes => 16;
|
||||
public int BlockSizeInBytes => _aeadBlockCipher.GetBlockSize();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper that generates a random new key on each call.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] NewKey()
|
||||
public AESGCM()
|
||||
{
|
||||
var key = new byte[KeyBitSize / 8];
|
||||
Random.NextBytes(key);
|
||||
return key;
|
||||
_blockCipher = new TBlockCipher();
|
||||
_aeadBlockCipher = new GcmBlockCipher(_blockCipher);
|
||||
}
|
||||
|
||||
|
||||
public string Encrypt(string plainText, SecureString encryptionKey)
|
||||
{
|
||||
var encryptedText = SimpleEncryptWithPassword(plainText, encryptionKey.ConvertToUnsecureString());
|
||||
@@ -178,14 +174,13 @@ namespace mRemoteNG.Security
|
||||
var nonce = new byte[NonceBitSize / 8];
|
||||
Random.NextBytes(nonce, 0, nonce.Length);
|
||||
|
||||
var cipher = new GcmBlockCipher(new AesFastEngine());
|
||||
var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
|
||||
cipher.Init(true, parameters);
|
||||
_aeadBlockCipher.Init(true, parameters);
|
||||
|
||||
//Generate Cipher Text With Auth Tag
|
||||
var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
|
||||
var len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);
|
||||
cipher.DoFinal(cipherText, len);
|
||||
var cipherText = new byte[_aeadBlockCipher.GetOutputSize(secretMessage.Length)];
|
||||
var len = _aeadBlockCipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);
|
||||
_aeadBlockCipher.DoFinal(cipherText, len);
|
||||
|
||||
//Assemble Message
|
||||
using (var combinedStream = new MemoryStream())
|
||||
@@ -228,19 +223,17 @@ namespace mRemoteNG.Security
|
||||
//Grab Nonce
|
||||
var nonce = cipherReader.ReadBytes(NonceBitSize / 8);
|
||||
|
||||
var cipher = new GcmBlockCipher(new AesFastEngine());
|
||||
var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
|
||||
cipher.Init(false, parameters);
|
||||
_aeadBlockCipher.Init(false, parameters);
|
||||
|
||||
//Decrypt Cipher Text
|
||||
var cipherText = cipherReader.ReadBytes(encryptedMessage.Length - nonSecretPayloadLength - nonce.Length);
|
||||
var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];
|
||||
var plainText = new byte[_aeadBlockCipher.GetOutputSize(cipherText.Length)];
|
||||
|
||||
try
|
||||
{
|
||||
var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
|
||||
cipher.DoFinal(plainText, len);
|
||||
|
||||
var len = _aeadBlockCipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
|
||||
_aeadBlockCipher.DoFinal(plainText, len);
|
||||
}
|
||||
catch (InvalidCipherTextException)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user