Skip to content

Instantly share code, notes, and snippets.

@beveradb
Created October 12, 2015 21:38
Show Gist options
  • Save beveradb/db41b9b73a1c8cea7709 to your computer and use it in GitHub Desktop.
Save beveradb/db41b9b73a1c8cea7709 to your computer and use it in GitHub Desktop.
Example AES CTR 256 bit encryption with no IV in C#
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
public class Program
{
public static void Main(String[] args)
{
// Define string data to be encrypted - in this case this is an object encoded as a JSON string for convenience
string inputString = "{\"DeliveryDate\": \"2015-10-09\", \"CustomerId\": \"2548\", \"PodId\": \"254\"}";
// Get UTF8 byte array of input string for encryption
byte[] inputBytes = ASCIIEncoding.UTF8.GetBytes(inputString);
// Define string to use as symmetrical encryption key - this must be known at both ends to decrypt
string keyString = "ThisShouldBecomeA32ByteSecretKey";
// Again, get UTF8 byte array of key for use in encryption
byte[] keyBytes = ASCIIEncoding.UTF8.GetBytes(keyString);
// Initialize AES CTR (counter) mode cipher from the BouncyCastle cryptography library
IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
// Set cipher parameters to use the encryption key we defined above for encryption
// Since we are encrypting using the CTR mode / algorithm, the cipher is operating as a stream cipher.
// For perfect secrecy with a stream cipher, we should be generating a stream of pseudorandom characters called a keystream,
// then XOR'ing that with the plaintext. Instead, for convenience we are just XOR'ing the first [blocksize] bytes of null values.
// While convenient, as we only need a single key for two way encryption/decryption, this method is vulnerable to a simple known-plaintext attack
// As such, it should not be relied upon for true secrecy, only for security through obscurity.
cipher.Init(true, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", keyBytes), new byte[16]));
// As this is a stream cipher, you can process bytes chunk by chunk until complete, then close with DoFinal.
// In our case we don't need a stream, so we simply call DoFinal() to encrypt the entire input at once.
byte[] encryptedBytes = cipher.DoFinal(inputBytes);
// The encryption is complete, however we still need to get the encrypted byte array into a useful form for passing as a URL parameter
// First, we convert the encrypted byte array to a Base64 string to make it use ASCII characters
string base64EncryptedOutputString = Convert.ToBase64String(encryptedBytes);
Console.Write("\n" + base64EncryptedOutputString);
// Lastly, we replace the 2 characters from Base64 which are not URL safe ( + and / ) with ( - and _ ) as recommended in IETF RFC4648
string urlEncodedBase64EncryptedOutputString = base64EncryptedOutputString.Replace("+", "-").Replace("/", "_");
// This final string is now safe to be passed around, into our web service by URL, etc.
Console.Write("\n" + urlEncodedBase64EncryptedOutputString);
}
}
@Khaingwityee
Copy link

This code is clear. How can I follow this code for AES CTR 128 bit encryption? .Thanks.

@ivadotnet
Copy link

Hi, the code expanation is great. But what about we want to use Initialization Vector.
I tried with these modifications:

cipher.Init(true, new ParametersWithIV(ParameterUtilities.CreateKeyParameter("AES", keyBytes), iv)); //instead of new byte[16], i put my array.

byte[] encryptedBytes = new byte[cipher.GetOutputSize(inputBytes.Length)];
int length = cipher.ProcessBytes(inputBytes, encryptedBytes , 0);
cipher.DoFinal(encryptedBytes, length);

Can you telll me what I am doing wrong?
Best regards, Iva

@Harrish-Selvarajah
Copy link

Hi,
would like to know how decryption in AES-CTR-256 would happen :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment