TripleDES algorithm in C# - c#

I'm currently working on TripleDES encryption in C# for which I've received the code sample from JAVA.
I have created an encryption function in C# with below code sample :
Inputs :
key/ekay = "15ce89cd1a2a838f4f6d49d60438251915ce89cd1a2a838f"
text/data = "0000000000000000"
public static string encryptionMethod(string Text, string key)
{
string encryptedText = string.Empty;
try
{
MD5CryptoServiceProvider md5Hash = new MD5CryptoServiceProvider();
byte[] md5Bytes = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(key));
md5Hash.Clear();
byte[] clearBytes = Encoding.UTF8.GetBytes(Text);
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.KeySize = 128;
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.None;
des.Key = md5Bytes; //Passing key in byte array
//des.BlockSize = 64;
byte[] ivBytes = new byte[8] {0, 0, 0, 0, 0, 0, 0, 0 };
des.IV = ivBytes;
ICryptoTransform ct = des.CreateEncryptor(); //Interface with some result
byte[] resultArray = ct.TransformFinalBlock(clearBytes, 0, clearBytes.Length);
encryptedText = ByteArrayToHexString(resultArray);
}
catch (Exception exception)
{
return "";
}
return encryptedText;
}
public static string ByteArrayToHexString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
but after comparing the C# output with JAVA output, I got the different results.
JAVA code
public static String encrypt(String data, String ekey) {
String encrypteddata = null;
try{
String key = ekey;
byte[] encryptKey = ISOUtil.hex2byte(key);
DESedeKeySpec spec = new DESedeKeySpec(encryptKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey theKey = keyFactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
IvParameterSpec IvParameters = new IvParameterSpec( new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
cipher.init(Cipher.ENCRYPT_MODE, theKey, IvParameters);
String plain = data;
byte[] plaintext = ISOUtil.hex2byte(plain);
byte[] encrypted = cipher.doFinal(plaintext);
encrypteddata= ISOUtil.byte2hex(encrypted);
}
catch(Exception e){
}
return encrypteddata;
}
output :
C# : eca27a1e639900f3298a5090cc34dd29
JAVA : c0a946402dd20f5e
Any help would be appreciated?
Thanks.

Here is the modified code, that has solved my issue.
public static string encryptionMethod(string Text, string key)
{
string encryptedText = string.Empty;
try
{
byte[] clearBytes = StringToByteArray(Text); ;//Encoding.UTF8.GetBytes(Text);
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.KeySize = 128;
des.Mode = CipherMode.CBC;
des.Padding = PaddingMode.None;
des.Key = StringToByteArray(key); //Passing key in byte array
//des.BlockSize = 64;
byte[] ivBytes = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
des.IV = ivBytes;
ICryptoTransform ct = des.CreateEncryptor(); //Interface with some result
byte[] resultArray = ct.TransformFinalBlock(clearBytes, 0, clearBytes.Length);
encryptedText = ByteArrayToHexString(resultArray);
}
catch (Exception exception)
{
return "";
}
return encryptedText;
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}

Related

Issues implementing SHA256 hash, then pbkdf2Sync and finally cipher with AES-256-cbc - c# to Nodejs

I have been given some c# code which implements SHA256 hashing and then AES-256-cbc. Now I have to translate the same to NodeJS. I tried several option, documentation and question/answers here, but none helped. As I am working with encryption for the first time, possibly something going wrong with encoding - but can't figure out exactly what.
Here is c# implementation:
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
public class HelloWorld
{
public static void Main(string[] args)
{
HelloWorld h1 = new HelloWorld();
Console.WriteLine(h1.EncryptText("Vitthal", "Vitthal"));
}
public string EncryptText(string pInput, string password)
{
byte[] bytesToBeEncrypted = Encoding.UTF8.GetBytes(GenerateSHA256String(pInput));
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
string result = Convert.ToBase64String(bytesEncrypted);
return result;
}
// method name GenerateSHA256String and code
public string GenerateSHA256String(string inputString)
{
StringBuilder stringBuilder = new StringBuilder();
try
{
SHA256 sha256 = SHA256Managed.Create();
byte[] bytes = Encoding.UTF8.GetBytes(inputString);
byte[] hash = sha256.ComputeHash(bytes);
for (int i = 0; i <= hash.Length - 1; i++)
stringBuilder.Append(hash[i].ToString("X2"));
return stringBuilder.ToString();
}
catch (Exception ex)
{
}
return stringBuilder.ToString();
}
// method name AES_Encrypt and code
private byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes)
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new System.Security.Cryptography.Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
cs.Close();
}
encryptedBytes = ms.ToArray();
}
}
return encryptedBytes;
}
}
And here is the NodeJS implementation using crypto:
const GenerateSHA256String = (object) => {
const buff = Buffer.from(object.toString());
const hash = createHash('sha256');
hash.update(buff);
const hashed = hash.digest('hex');
return hashed;
}
const getEncryptedChecksum = (object) => {
const payload = GenerateSHA256String(object);
console.log(Buffer.from(payload));
const passKey = Buffer.from('Vitthal');
const saltString = [1,2,3,4,5,6,7,8];
const key = pbkdf2Sync(GenerateSHA256String(passKey), Buffer.from(saltString), 1000, 100, 'sha1');
const encKey = key.subarray(0, 32);
const encIV = key.subarray(32, 48);
const cipher = createCipheriv('aes-256-cbc', encKey, encIV);
let encrypted = cipher.update(Buffer.from(payload), 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
console.log(getEncryptedChecksum('Vitthal'));
Any help in this regard is highly appreciated.
Finally solved. It was encoding issue. Some strange behaviors different between c# & nodejs. Anyways, here is the final nodejs code that works!
const GenerateSHA256String = (object, encoding) => {
const buff = Buffer.from(object.toString());
const hash = createHash('sha256');
hash.update(buff);
const hashed = hash.digest(encoding ? encoding : null);
return hashed;
}
const getEncryptedChecksum = (object) => {
const payload = GenerateSHA256String(object, 'hex');
const payBuff = Buffer.from(payload.toUpperCase());
const passKey = Buffer.from('NDSICDM');
const saltString = [1,2,3,4,5,6,7,8];
const key = pbkdf2Sync(GenerateSHA256String(passKey), Buffer.from(saltString), 1000, 64, 'sha1');
const encKey = key.subarray(0, 32);
const encIV = key.subarray(32, 48);
const cipher = createCipheriv('aes-256-cbc', encKey, encIV);
let encrypted = cipher.update(payBuff, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}

PHP and C# AES256 encryption -> decryption

I want to encrypt a text in PHP and to decrypt in in C#, but i can't.
This is my PHP code:
define('AES_256_ECB', 'aes-256-ecb');
$encryption_key = "SomeSimpleTest";
$data = "Test123";
$encryptedData = openssl_encrypt($data, AES_256_ECB, $encryption_key, 0);
..and this is my C# code:
(AESEncryption.cs class)
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace AESCrypto
{
class AESEncryption
{
public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes)
{
byte[] decryptedBytes = null;
// Set your salt here to meet your flavor:
byte[] saltBytes = passwordBytes;
// Example:
//saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 256;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.ECB;
//AES.Padding = PaddingMode.PKCS7;
using (CryptoStream cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return decryptedBytes;
}
public static string Decrypt(string decryptedText, byte[] passwordBytes)
{
byte[] bytesToBeDecrypted = Convert.FromBase64String(decryptedText);
// Hash the password with SHA256
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] decryptedBytes = AES_Decrypt(bytesToBeDecrypted, passwordBytes);
// Getting the size of salt
int saltSize = GetSaltSize(passwordBytes);
// Removing salt bytes, retrieving original bytes
byte[] originalBytes = new byte[decryptedBytes.Length - saltSize];
for (int i = saltSize; i < decryptedBytes.Length; i++)
{
originalBytes[i - saltSize] = decryptedBytes[i];
}
return Encoding.UTF8.GetString(originalBytes);
}
public static int GetSaltSize(byte[] passwordBytes)
{
var key = new Rfc2898DeriveBytes(passwordBytes, passwordBytes, 1000);
byte[] ba = key.GetBytes(2);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ba.Length; i++)
{
sb.Append(Convert.ToInt32(ba[i]).ToString());
}
int saltSize = 0;
string s = sb.ToString();
foreach (char c in s)
{
int intc = Convert.ToInt32(c.ToString());
saltSize = saltSize + intc;
}
return saltSize;
}
public static byte[] GetRandomBytes(int length)
{
byte[] ba = new byte[length];
RNGCryptoServiceProvider.Create().GetBytes(ba);
return ba;
}
}
}
Usage of it:
using AESCrypto;
...
public string DecryptText(string input, string password)
{
// Get the bytes of the string
byte[] bytesToBeDecrypted = Convert.FromBase64String(input);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] bytesDecrypted = AESEncryption.AES_Decrypt(bytesToBeDecrypted, passwordBytes);
string result = Encoding.UTF8.GetString(bytesDecrypted);
return result;
}
private void btn1_Click(object sender, EventArgs e)
{
textBox1.Text = DecryptText("KEY_ENCRYPTED_WITH_PHP", "SomeSimpleTest");
}
I even tried with CBC but does not work...The mode of encryption is not important. I only want to make it work as it should.
Thanks.
php code:
define('AES_128_ECB', 'aes-128-ecb');
$encryption_key = "MY_16_CHAR_KEY:)";
$data = "MyOwnEncryptedSecretText";
$encryptedData = openssl_encrypt($data, AES_128_ECB, $encryption_key, 0);
C# code:
public String Decrypt(String text, String key)
{
//decode cipher text from base64
byte[] cipher = Convert.FromBase64String(text);
//get key bytes
byte[] btkey = Encoding.ASCII.GetBytes(key);
//init AES 128
RijndaelManaged aes128 = new RijndaelManaged();
aes128.Mode = CipherMode.ECB;
aes128.Padding = PaddingMode.PKCS7;
//decrypt
ICryptoTransform decryptor = aes128.CreateDecryptor(btkey, null);
MemoryStream ms = new MemoryStream(cipher);
CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
byte[] plain = new byte[cipher.Length];
int decryptcount = cs.Read(plain, 0, plain.Length);
ms.Close();
cs.Close();
//return plaintext in String
return Encoding.UTF8.GetString(plain, 0, decryptcount);
}
and usage of it:
string DecryptedText = Decrypt("GENERATED_KEY", "MY_16_CHAR_KEY:)");
Now it works great :)
Thanks.

Decrypt string by other string in c#

I have two strings as bellow:
String A = 29CEDC4A435DD625 (key)
String B = 5272B624753D79AF (encodedText)
I try to do decrypt string B by String A to get out the result: 8BC141DCC122B74F but don't successful with the decrypt function as follow:
public static string Decrypt (string encodedText, string key)
{
TripleDESCryptoServiceProvider desCrytoProvider = new TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider hashMD5Provider = new MD5CryptoServiceProvider();
byte[] byteHash;
byte[] byteBuff;
byteHash = hashMD5Provider.ComputeHash(Encoding.UTF8.GetBytes(key));
desCrytoProvider.Key = byteHash;
desCrytoProvider.Mode = CipherMode.ECB;
byteBuff = Convert.FromBase64String(encodedText);
string plaintext = Encoding.UTF8.GetString(desCrytoProvider.CreateDecryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
return plaintext;
}
I think you have a trouble with converting from byte array to String and vice versa. Try to use Convert.ToBase64String(...), Convert.FromBase64String(...). It works:
static TripleDESCryptoServiceProvider desCrytoProvider = new TripleDESCryptoServiceProvider();
static MD5CryptoServiceProvider hashMD5Provider = new MD5CryptoServiceProvider();
static void Main(string[] args)
{
String key = "29CEDC4A435DD625";//(key)
String encodedText = Encrypt("just4fun", key);
Console.WriteLine(Decrypt(encodedText, key));
}
public static String Encrypt(String text, String key)
{
byte[] byteHash;
byte[] byteBuff;
var bytes = Encoding.UTF8.GetBytes(key);
byteHash = hashMD5Provider.ComputeHash(bytes);
desCrytoProvider.Key = byteHash;
desCrytoProvider.Mode = CipherMode.ECB;
byteBuff = Encoding.UTF8.GetBytes(text);
return Convert.ToBase64String(desCrytoProvider.CreateEncryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
}
public static String Decrypt(String encodedText, String key)
{
byte[] byteHash;
byte[] byteBuff;
var bytes = Encoding.UTF8.GetBytes(key);
byteHash = hashMD5Provider.ComputeHash(bytes);
desCrytoProvider.Key = byteHash;
desCrytoProvider.Mode = CipherMode.ECB;
byteBuff = Convert.FromBase64String(encodedText);
return Encoding.UTF8.GetString(desCrytoProvider.CreateDecryptor().TransformFinalBlock(byteBuff, 0, byteBuff.Length));
}

C# 3DES Encryption+Decryption (ECB+No padding+no IV)

I need to encrypt and decrypt a string in C#.
I have managed to write the right decoder for a string which I receive from a Java service - 3DES, DESede/ECB/NoPadding.
Now, I am having some a time encoding a string accordingly.
Below is the decryptor (which is perfect and not need any changes).
attached also the encryptor which should encrypt a string that will be decrypted with the attached decryptor.
decryptor:
public static string Decryptor240815B(string Message) /* Working */
{
string cipher = Message.Replace(" ", "+");
byte[] keyBytes;
string cipherString = FromHexString(cipher);
byte[] cipherBytes = Convert.FromBase64String(cipherString);
keyBytes = UTF8Encoding.UTF8.GetBytes(seed);
var tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyBytes;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.None;
ICryptoTransform transformation = tdes.CreateDecryptor();
byte[] decryptedBytes = transformation.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
tdes.Clear();
string response = UTF8Encoding.UTF8.GetString(decryptedBytes);
return response;
}
public static string FromHexString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return Encoding.UTF8.GetString(bytes);
}
encryptor (need change):
public static string Encrypt030915(string message)
{
byte[] keyBytes = UTF8Encoding.UTF8.GetBytes(seed);
//string hexedMSG = StringToHexString(message);
byte[] textBytes = UTF8Encoding.UTF8.GetBytes(message);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
ICryptoTransform cTransform = tdes.CreateEncryptor();
tdes.Key = keyBytes;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.None;
byte[] resultArray = cTransform.TransformFinalBlock(textBytes, 0, textBytes.Length);
tdes.Clear();
string base64 = Convert.ToBase64String(resultArray);
string retVal = FromBase64ToHEX(base64);
return retVal;
//byte[] ba = Encoding.UTF8.GetBytes(base64);
// return ToHexString(resultArray);
//return ByteArrayToString030915(ba);
}
private static string FromBase64ToHEX(string base64)
{
char[] c = new char[base64.Length * 2];
byte b;
for (int i = 0; i < base64.Length; ++i)
{
b = ((byte)(base64[i] >> 4));
c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
b = ((byte)(base64[i] & 0xF));
c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
}
return new string(c);
}
You need to move the
ICryptoTransform transformation = tdes.CreateDecryptor();
line below setting the parameters, as CreateDecryptor uses the parameters (like Key!) as they are set on the TripleDESCryptoServiceProvider at the moment. But in your original code, you create the decryptor and only after that set the decryption parameters, which do not get used at all (and the decryptor gets to use a random key instead). Replace the relevant lines with:
var tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyBytes;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.None;
ICryptoTransform transformation = tdes.CreateDecryptor();
and it will work.
However, note that your code is 1) unnecessarily complicated, 2) completely insecure.

Encrypt string with Bouncy Castle AES/CBC/PKCS7

I have been looking everywhere for some sample code on how to encrypt a simple string with the encryption in the title using the Bouncy Castle Framework.
This code will run on a Windows Universal project.
My previous attempts to encrypt using the build in API's failed to decrypt on the server.
I tried this: which gives me a string like:
4pQUfomwVVsl68oQqWoWYNRmRM+Cp+vNFXBNdkN6dZPQ34VZ35vsKn9Q7QGTDVOj+w5mqVYHnGuAOFOgdgl8kA==
s = String.Format("{0}_{1}", s, DateTime.Now.ToString("ddMMyyyyHmmss"));
SymmetricKeyAlgorithmProvider algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
IBuffer keymaterial = CryptographicBuffer.ConvertStringToBinary("[Key]", BinaryStringEncoding.Utf8);
CryptographicKey KEY = algorithm.CreateSymmetricKey(keymaterial);
IBuffer IV = CryptographicBuffer.ConvertStringToBinary("[IV]", BinaryStringEncoding.Utf8);
IBuffer data = CryptographicBuffer.ConvertStringToBinary(s, BinaryStringEncoding.Utf8);
IBuffer output = CryptographicEngine.Encrypt(KEY, data, IV);
return CryptographicBuffer.EncodeToBase64String(output);
The server does encryption/decryption with
public static string Encrypt(string text, byte[] key, byte[] iv, int keysize = 128, int blocksize = 128, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = blocksize;
aes.KeySize = keysize;
aes.Mode = cipher;
aes.Padding = padding;
byte[] src = Encoding.UTF8.GetBytes(text);
using (ICryptoTransform encrypt = aes.CreateEncryptor(key, iv))
{
byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
encrypt.Dispose();
return Convert.ToBase64String(dest);
}
}
public static string Decrypt(string text, byte[] key, byte[] iv, int keysize = 128, int blocksize = 128, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.BlockSize = blocksize;
aes.KeySize = keysize;
aes.Mode = cipher;
aes.Padding = padding;
byte[] src = Convert.FromBase64String(text);
using (ICryptoTransform decrypt = aes.CreateDecryptor(key, iv))
{
byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
decrypt.Dispose();
return Encoding.UTF8.GetString(dest); //Padding is invalid and cannot be removed.
}
}
But it fails becasue:
Padding is invalid and cannot be removed.
That's why I want to try Bouncy Castle, but I can't find any suitable example code.
EDIT
I tried using Bouncy Castle with the code provided in the answer.
Now I'm getting the error:
initialisation vector must be the same length as block size
byte[] inputBytes = Encoding.UTF8.GetBytes(s);
byte[] IV = Encoding.UTF8.GetBytes("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
byte[] key = Encoding.UTF8.GetBytes("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
//Set up
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
Debug.WriteLine(IV.Length); //32
Debug.WriteLine(cipher.GetBlockSize()); //16
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIv = new ParametersWithIV(keyParam, IV);
cipher.Init(true, keyParamWithIv); //Error Message thrown
byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)]; //cip
int length = cipher.ProcessBytes(inputBytes, outputBytes, 0);
cipher.DoFinal(outputBytes, length); //Do the final block
string encryptedInput = Convert.ToBase64String(outputBytes);
The length on the server is 128. How can I force it to be equal and same length?
Here are snippets I use. It uses the default built-in System.Security.Cryptography. It doesn't need to be BC
/// <summary>
/// Encrypt a byte array using AES 128
/// </summary>
/// <param name="key">128 bit key</param>
/// <param name="secret">byte array that need to be encrypted</param>
/// <returns>Encrypted array</returns>
public static byte[] EncryptByteArray(byte[] key, byte[] secret)
{
using (MemoryStream ms = new MemoryStream())
{
using (AesManaged cryptor = new AesManaged())
{
cryptor.Mode = CipherMode.CBC;
cryptor.Padding = PaddingMode.PKCS7;
cryptor.KeySize = 128;
cryptor.BlockSize = 128;
//We use the random generated iv created by AesManaged
byte[] iv = cryptor.IV;
using (CryptoStream cs = new CryptoStream(ms, cryptor.CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(secret, 0, secret.Length);
}
byte[] encryptedContent = ms.ToArray();
//Create new byte array that should contain both unencrypted iv and encrypted data
byte[] result = new byte[iv.Length + encryptedContent.Length];
//copy our 2 array into one
System.Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
System.Buffer.BlockCopy(encryptedContent, 0, result, iv.Length, encryptedContent.Length);
return result;
}
}
}
/// <summary>
/// Decrypt a byte array using AES 128
/// </summary>
/// <param name="key">key in bytes</param>
/// <param name="secret">the encrypted bytes</param>
/// <returns>decrypted bytes</returns>
public static byte[] DecryptByteArray(byte[] key, byte[] secret)
{
byte[] iv = new byte[16]; //initial vector is 16 bytes
byte[] encryptedContent = new byte[secret.Length - 16]; //the rest should be encryptedcontent
//Copy data to byte array
System.Buffer.BlockCopy(secret, 0, iv, 0, iv.Length);
System.Buffer.BlockCopy(secret, iv.Length, encryptedContent, 0, encryptedContent.Length);
using (MemoryStream ms = new MemoryStream())
{
using (AesManaged cryptor = new AesManaged())
{
cryptor.Mode = CipherMode.CBC;
cryptor.Padding = PaddingMode.PKCS7;
cryptor.KeySize = 128;
cryptor.BlockSize = 128;
using (CryptoStream cs = new CryptoStream(ms, cryptor.CreateDecryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(encryptedContent, 0, encryptedContent.Length);
}
return ms.ToArray();
}
}
}
If you really need BC, here is a quick test I manage to write based on the test suit from https://github.com/bcgit/bc-csharp/blob/master/crypto/test/src/crypto/test/AESFastTest.cs
You can tailor it for your need
private static void TestBC()
{
//Demo params
string keyString = "jDxESdRrcYKmSZi7IOW4lw==";
string input = "abc";
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] iv = new byte[16]; //for the sake of demo
//Set up
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine); //CBC
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); //Default scheme is PKCS5/PKCS7
KeyParameter keyParam = new KeyParameter(Convert.FromBase64String(keyString));
ParametersWithIV keyParamWithIV = new ParametersWithIV(keyParam, iv, 0, 16);
// Encrypt
cipher.Init(true, keyParamWithIV);
byte[] outputBytes = new byte[cipher.GetOutputSize(inputBytes.Length)];
int length = cipher.ProcessBytes(inputBytes, outputBytes, 0);
cipher.DoFinal(outputBytes, length); //Do the final block
string encryptedInput = Convert.ToBase64String(outputBytes);
Console.WriteLine("Encrypted string: {0}", encryptedInput);
//Decrypt
cipher.Init(false, keyParamWithIV);
byte[] comparisonBytes = new byte[cipher.GetOutputSize(outputBytes.Length)];
length = cipher.ProcessBytes(outputBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length); //Do the final block
Console.WriteLine("Decrypted string: {0}",Encoding.UTF8.GetString(comparisonBytes)); //Should be abc
}
enter link description here
byte[] k; //32 byte
string para; // plaintext
string msgRefNo; // 16byte
byte[] inputBytes = Encoding.UTF8.GetBytes(para);
byte[] IV = Encoding.UTF8.GetBytes(msgRefNo);
byte[] key = k;
AesEngine engine = new AesEngine();
CbcBlockCipher blockCipher = new CbcBlockCipher(engine);
PaddedBufferedBlockCipher cipher1 = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
KeyParameter keyParam = new KeyParameter(key);
ParametersWithIV keyParamWithIv = new ParametersWithIV(keyParam, IV);
cipher1.Init(true, keyParamWithIv); //Error Message thrown
byte[] outputBytes = new byte[cipher1.GetOutputSize(inputBytes.Length)]; //cip
int length = cipher1.ProcessBytes(inputBytes, outputBytes, 0);
cipher1.DoFinal(outputBytes, length); //Do the final block
string encryptedInput = Convert.ToBase64String(outputBytes);
return encryptedInput;

Categories