-
-
Save elevine/47f8365936eb595c4beaf46283570825 to your computer and use it in GitHub Desktop.
Example AES CTR 256 bit encryption with no IV in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment