Skip to content

Instantly share code, notes, and snippets.

@trinnguyen
Created September 13, 2020 16:37
Show Gist options
  • Save trinnguyen/e19af4cf850bb3a69211315c07f6c672 to your computer and use it in GitHub Desktop.
Save trinnguyen/e19af4cf850bb3a69211315c07f6c672 to your computer and use it in GitHub Desktop.
C# Encrypt/Decrypt with BouncyCastle
using System;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace TnnCrypto
{
public class AesGcmAead
{
private const int MacSize = 16 * 8;
private const int NonceSizeBytes = 12;
public byte[] Encrypt(byte[] keyBytes, byte[] plainBytes, byte[] associatedBytes)
{
var rdNonce = new byte[NonceSizeBytes];
var srng = new SecureRandom();
srng.NextBytes(rdNonce);
// encrypt
GcmBlockCipher c = CreateGcmCipher(true, keyBytes, associatedBytes, rdNonce);
var cipherBytes = new byte[c.GetOutputSize(plainBytes.Length)];
int len = c.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherBytes, 0);
c.DoFinal(cipherBytes, len);
// append nonce to the beginning
return ConcatBytes(rdNonce, cipherBytes);
}
public byte[] Decrypt(byte[] keyBytes, byte[] cipherBytes, byte[] associatedBytes)
{
// extract the nonce
byte[] nonce = new byte[NonceSizeBytes];
Buffer.BlockCopy(cipherBytes, 0, nonce, 0, NonceSizeBytes);
// extract
GcmBlockCipher c = CreateGcmCipher(false, keyBytes, associatedBytes, nonce);
int rawCipherLen = cipherBytes.Length - NonceSizeBytes;
var plainBytes = new byte[c.GetOutputSize(rawCipherLen)];
int len = c.ProcessBytes(cipherBytes, NonceSizeBytes, rawCipherLen, plainBytes, 0);
c.DoFinal(plainBytes, len);
// return
return plainBytes;
}
private static GcmBlockCipher CreateGcmCipher(bool forEncryption, byte[] keyBytes, byte[] associatedBytes, byte[] rdNonce)
{
var parameters = new AeadParameters(new KeyParameter(keyBytes), MacSize, rdNonce, associatedBytes);
var c = new GcmBlockCipher(new AesEngine());
c.Init(forEncryption, parameters);
return c;
}
private static byte[] ConcatBytes(byte[] bt1, byte[] bt2)
{
var combinedBytes = new byte[bt1.Length + bt2.Length];
Buffer.BlockCopy(bt1, 0, combinedBytes, 0, bt1.Length);
Buffer.BlockCopy(bt2, 0, combinedBytes, bt1.Length, bt2.Length);
return combinedBytes;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment