Skip to content

Instantly share code, notes, and snippets.

@ryno1234
Last active October 25, 2023 18:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ryno1234/ea34415643d109974b6f to your computer and use it in GitHub Desktop.
Save ryno1234/ea34415643d109974b6f to your computer and use it in GitHub Desktop.
Rijndael encrypt / decrypt in C# provided by Phil Fresle (see comments) along with a helper class (AspRijndael) to provide interoperability between Phil's C# version and his original VB Script version.
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
using System.EnterpriseServices;
using System.Globalization;
namespace RijndaelNs
{
public class AspRijndael
{
public string EncryptData(string message, string password)
{
byte[] result = Rijndael.EncryptData(
Encoding.ASCII.GetBytes(message),
Encoding.ASCII.GetBytes(password),
new byte[] { },
Rijndael.BlockSize.Block256,
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeECB
);
StringBuilder hexResult = new StringBuilder(result.Length * 2);
foreach (byte b in result)
hexResult.AppendFormat("{0:x2}", b);
return hexResult.ToString();
}
public string DecryptData(string encryptedMessage, string password)
{
if (encryptedMessage.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] byteArr = new byte[encryptedMessage.Length / 2];
for (int index = 0; index < byteArr.Length; index++)
{
string byteValue = encryptedMessage.Substring(index * 2, 2);
byteArr[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
byte[] result = Rijndael.DecryptData(
byteArr,
Encoding.ASCII.GetBytes(password),
new byte[] { },
Rijndael.BlockSize.Block256,
Rijndael.KeySize.Key256,
Rijndael.EncryptionMode.ModeECB
);
return ASCIIEncoding.ASCII.GetString(result);
}
}
/// <summary>
/// AUTHOR: Phil Fresle
/// COPYRIGHT: Copyright 2001-2005 Phil Fresle
/// EMAIL: phil@frez.co.uk
/// WEB: http://www.frez.co.uk
/// Implementation of the AES Rijndael Block Cipher, converted from my VB6 version.
/// Inspired by Mike Scott's implementation in C. Permission for free direct or
/// derivative use is granted subject to compliance with any conditions that the
/// originators of the algorithm place on its exploitation.
///
/// The Rijndael home page is here:-
/// http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/
///
/// NOTE: All string conversions assume strings are Unicode; this may yield different
/// results from other implementations if the other implementations are based
/// on Ascii strings. Unicode is a 2-byte character set, and means that the routines
/// will work just fine on, for instance, Japanese text.
///
/// MODIFICATION HISTORY:
/// 16-Feb-2001 Phil Fresle Initial VB6 Version
/// 03-Apr-2001 Phil Fresle Added EncryptData and DecryptData functions to
/// VB6 version.
/// 19-Apr-2001 Phil Fresle Thanks to Paolo Migliaccio for finding a bug
/// with 256 bit key in VB6 version.
/// 11-Jul-2005 Phil Fresle Initial C# version.
/// </summary>
///
public static class Rijndael
{
public enum BlockSize { Block128, Block192, Block256 };
public enum KeySize { Key128, Key192, Key256 };
public enum EncryptionMode { ModeECB, ModeCBC };
public enum CharacterSet { CharsUnicode, CharsAscii };
private static byte[] InCo = { 0xB, 0xD, 0x9, 0xE };
private static byte[] fbsub = new byte[256];
private static byte[] rbsub = new byte[256];
private static byte[] ptab = new byte[256];
private static byte[] ltab = new byte[256];
private static uint[] ftable = new uint[256];
private static uint[] rtable = new uint[256];
private static uint[] rco = new uint[30];
private static int Nk, Nb, Nr;
private static byte[] fi = new byte[24];
private static byte[] ri = new byte[24];
private static uint[] fkey = new uint[120];
private static uint[] rkey = new uint[120];
private static byte RotateLeft(byte valueToShift, int shiftBits)
{
// Rotate the bits in the byte
return (byte)((valueToShift << shiftBits) |
(valueToShift >> (8 - shiftBits)));
}
private static uint RotateLeft(uint valueToShift, int shiftBits)
{
// Rotate the bits in the integer
return (valueToShift << shiftBits) |
(valueToShift >> (32 - shiftBits));
}
private static uint Pack(byte[] b)
{
uint temp = 0;
for (byte i = 0; i <= 3; i++)
temp |= ((uint)b[i] << (i * 8));
return temp;
}
private static uint PackFrom(byte[] b, int k)
{
uint temp = 0;
for (byte i = 0; i <= 3; i++)
temp |= ((uint)b[i + k] << (i * 8));
return temp;
}
private static void Unpack(uint a, byte[] b)
{
b[0] = (byte)a;
b[1] = (byte)(a >> 8);
b[2] = (byte)(a >> 16);
b[3] = (byte)(a >> 24);
}
private static void UnpackFrom(uint a, byte[] b, int k)
{
b[0 + k] = (byte)a;
b[1 + k] = (byte)(a >> 8);
b[2 + k] = (byte)(a >> 16);
b[3 + k] = (byte)(a >> 24);
}
private static byte xtime(byte a)
{
byte b;
if ((a & 0x80) != 0)
b = 0x1b;
else
b = 0;
a <<= 1;
a ^= b;
return a;
}
private static byte bmul(byte x, byte y)
{
if (x != 0 && y != 0)
return ptab[(ltab[x] + ltab[y]) % 255];
else
return 0;
}
private static uint SubByte(uint a)
{
byte[] b = new byte[4];
Unpack(a, b);
b[0] = fbsub[b[0]];
b[1] = fbsub[b[1]];
b[2] = fbsub[b[2]];
b[3] = fbsub[b[3]];
return Pack(b);
}
private static byte product(uint x, uint y)
{
byte[] xb = new byte[4];
byte[] yb = new byte[4];
Unpack(x, xb);
Unpack(y, yb);
return (byte)(bmul(xb[0], yb[0]) ^ bmul(xb[1], yb[1]) ^
bmul(xb[2], yb[2]) ^ bmul(xb[3], yb[3]));
}
private static uint InvMixCol(uint x)
{
uint y, m;
byte[] b = new byte[4];
m = Pack(InCo);
b[3] = product(m, x);
m = RotateLeft(m, 24);
b[2] = product(m, x);
m = RotateLeft(m, 24);
b[1] = product(m, x);
m = RotateLeft(m, 24);
b[0] = product(m, x);
y = Pack(b);
return y;
}
private static byte ByteSub(byte x)
{
byte y;
y = ptab[255 - ltab[x]];
x = y;
x = RotateLeft(x, 1);
y ^= x;
x = RotateLeft(x, 1);
y ^= x;
x = RotateLeft(x, 1);
y ^= x;
x = RotateLeft(x, 1);
y ^= x;
y ^= 0x63;
return y;
}
public static void gentables()
{
byte y;
byte[] b = new byte[4];
ltab[0] = 0;
ptab[0] = 1;
ltab[1] = 0;
ptab[1] = 3;
ltab[3] = 1;
for (int i = 2; i <= 255; i++)
{
ptab[i] = (byte)(ptab[i - 1] ^ xtime(ptab[i - 1]));
ltab[ptab[i]] = (byte)i;
}
fbsub[0] = 0x63;
rbsub[0x63] = 0;
for (int i = 1; i <= 255; i++)
{
y = ByteSub((byte)i);
fbsub[i] = y;
rbsub[y] = (byte)i;
}
y = 1;
for (int i = 0; i <= 29; i++)
{
rco[i] = y;
y = xtime(y);
}
for (int i = 0; i <= 255; i++)
{
y = fbsub[i];
b[3] = (byte)(y ^ xtime(y));
b[2] = y;
b[1] = y;
b[0] = xtime(y);
ftable[i] = Pack(b);
y = rbsub[i];
b[3] = bmul(InCo[0], y);
b[2] = bmul(InCo[1], y);
b[1] = bmul(InCo[2], y);
b[0] = bmul(InCo[3], y);
rtable[i] = Pack(b);
}
}
public static void gkey(int nb, int nk, byte[] key)
{
int i, j, k, m, N;
int C1, C2, C3;
uint[] CipherKey = new uint[8];
Nb = nb;
Nk = nk;
if (Nb >= Nk)
Nr = 6 + Nb;
else
Nr = 6 + Nk;
C1 = 1;
if (Nb < 8)
{
C2 = 2;
C3 = 3;
}
else
{
C2 = 3;
C3 = 4;
}
for (m = j = 0; j < nb; j++, m += 3)
{
fi[m] = (byte)((j + C1) % nb);
fi[m + 1] = (byte)((j + C2) % nb);
fi[m + 2] = (byte)((j + C3) % nb);
ri[m] = (byte)((nb + j - C1) % nb);
ri[m + 1] = (byte)((nb + j - C2) % nb);
ri[m + 2] = (byte)((nb + j - C3) % nb);
}
N = Nb * (Nr + 1);
for (i = j = 0; i < Nk; i++, j += 4)
CipherKey[i] = PackFrom(key, j);
for (i = 0; i < Nk; i++)
fkey[i] = CipherKey[i];
for (j = Nk, k = 0; j < N; j += Nk, k++)
{
fkey[j] = fkey[j - Nk] ^ SubByte(RotateLeft(fkey[j - 1], 24)) ^ rco[k];
if (Nk <= 6)
{
for (i = 1; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
else
{
for (i = 1; i < 4 && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
if ((j + 4) < N)
fkey[j + 4] = fkey[j + 4 - Nk] ^ SubByte(fkey[j + 3]);
for (i = 5; i < Nk && (i + j) < N; i++)
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
}
}
for (j = 0; j < Nb; j++)
rkey[j + N - Nb] = fkey[j];
for (i = Nb; i < (N - Nb); i += Nb)
{
k = N - Nb - i;
for (j = 0; j < Nb; j++)
rkey[k + j] = InvMixCol(fkey[i + j]);
}
for (j = (N - Nb); j < N; j++)
rkey[j - N + Nb] = fkey[j];
}
public static void encrypt(byte[] buff)
{
int i, j, k, m;
uint[] a = new uint[8];
uint[] b = new uint[8];
uint[] x, y, t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = PackFrom(buff, j);
a[i] ^= fkey[i];
}
k = Nb;
x = a;
y = b;
for (i = 1; i < Nr; i++)
{
for (m = j = 0; j < Nb; j++, m += 3)
y[j] = fkey[k++] ^ ftable[(byte)x[j]] ^
RotateLeft(ftable[(byte)(x[fi[m]] >> 8)], 8) ^
RotateLeft(ftable[(byte)(x[fi[m + 1]] >> 16)], 16) ^
RotateLeft(ftable[x[fi[m + 2]] >> 24], 24);
t = x;
x = y;
y = t;
}
for (m = j = 0; j < Nb; j++, m += 3)
y[j] = fkey[k++] ^ (uint)fbsub[(byte)x[j]] ^
RotateLeft((uint)fbsub[(byte)(x[fi[m]] >> 8)], 8) ^
RotateLeft((uint)fbsub[(byte)(x[fi[m + 1]] >> 16)], 16) ^
RotateLeft((uint)fbsub[x[fi[m + 2]] >> 24], 24);
for (i = j = 0; i < Nb; i++, j += 4)
{
UnpackFrom(y[i], buff, j);
x[i] = y[i] = 0;
}
}
public static void decrypt(byte[] buff)
{
int i, j, k, m;
uint[] a = new uint[8];
uint[] b = new uint[8];
uint[] x, y, t;
for (i = j = 0; i < Nb; i++, j += 4)
{
a[i] = PackFrom(buff, j);
a[i] ^= rkey[i];
}
k = Nb;
x = a;
y = b;
for (i = 1; i < Nr; i++)
{
for (m = j = 0; j < Nb; j++, m += 3)
y[j] = rkey[k++] ^ rtable[(byte)x[j]] ^
RotateLeft(rtable[(byte)(x[ri[m]] >> 8)], 8) ^
RotateLeft(rtable[(byte)(x[ri[m + 1]] >> 16)], 16) ^
RotateLeft(rtable[x[ri[m + 2]] >> 24], 24);
t = x;
x = y;
y = t;
}
for (m = j = 0; j < Nb; j++, m += 3)
y[j] = rkey[k++] ^ (uint)rbsub[(byte)x[j]] ^
RotateLeft((uint)rbsub[(byte)(x[ri[m]] >> 8)], 8) ^
RotateLeft((uint)rbsub[(byte)(x[ri[m + 1]] >> 16)], 16) ^
RotateLeft((uint)rbsub[x[ri[m + 2]] >> 24], 24);
for (i = j = 0; i < Nb; i++, j += 4)
{
UnpackFrom(y[i], buff, j);
x[i] = y[i] = 0;
}
}
// -------------------------------------------------------------------------------------
// The code below are utility functions for calling the Rijndael code above
// -------------------------------------------------------------------------------------
/// <summary>This version of EncryptData takes the message, password
/// and IV as byte arrays and encrypts the message, returning the encrypted text
/// as a byte array.
///
/// NOTE: In this implementation I add four bytes to the start of the message and
/// use that space to store the length of the message. Then the sister DecryptData
/// function knows where to trim the message before returning it. Not all
/// encryption routines will use this method. The only parts specified in the
/// Rijndael standard are for use of the gentables, gkey, encrypt and decrypt
/// functions. So if you have some data encrypted with another implementation
/// of Rijndael, or you are encypting data that will be decrypted with another
/// implementation, then you will need to know how they are recording the length of
/// the message (if at all), and if you are encrypting/decrypting strings whether
/// they based it on Ascii or Unicode (or some other character set).
/// </summary>
/// <param name="message">The encrypted message</param>
/// <param name="password">The password/key to encrypt the message with</param>
/// <param name="initialisationVector">The IV as a string</param>
/// <param name="blockSize">The block size used to encrypt the message</param>
/// <param name="keySize">The key size used to encrypt the message</param>
/// <param name="cryptMode">The encryption mode, CBC or ECB, used to encrypt the message</param>
public static byte[] EncryptData(byte[] message, byte[] password,
byte[] initialisationVector, BlockSize blockSize,
KeySize keySize, EncryptionMode cryptMode)
{
byte[] messageData, keyBlock, vectorBlock, dataBlock;
int messageLength, encodedLength, nb, nk;
// Dont do any work if message is empty
messageLength = message.Length;
if (messageLength <= 0)
return message;
// Set up arrays based on block size
switch (blockSize)
{
case BlockSize.Block128:
nb = 4;
break;
case BlockSize.Block192:
nb = 6;
break;
default: // assume 256
nb = 8;
break;
}
vectorBlock = new byte[nb * 4];
dataBlock = new byte[nb * 4];
for (int i = 0; i < (nb * 4); i++)
{
vectorBlock[i] = 0;
dataBlock[i] = 0;
}
// Set up array based on key size
switch (keySize)
{
case KeySize.Key128:
nk = 4;
break;
case KeySize.Key192:
nk = 6;
break;
default: // assume 256
nk = 8;
break;
}
keyBlock = new byte[nk * 4];
for (int i = 0; i < (nk * 4); i++)
{
keyBlock[i] = 0;
}
// Key will be zero padded, or trimmed to correct size
for (int i = 0; (i < password.Length) && (i < (nk * 4)); i++)
keyBlock[i] = password[i];
// Vector will be zero padded, or trimmed to correct size
for (int i = 0; (i < initialisationVector.Length) && (i < (nb * 4)); i++)
vectorBlock[i] = initialisationVector[i];
// Prepare the key and tables using the Rijndael fuinctions
gentables();
gkey(nb, nk, keyBlock);
// Add 4 bytes to message to store message length, then make sure the length
// is a Mod of the block size
encodedLength = messageLength + 4;
if ((encodedLength % (nb * 4)) != 0)
encodedLength += ((nb * 4) - (encodedLength % (nb * 4)));
messageData = new byte[encodedLength];
// Put message length on front of message
messageData[0] = (byte)messageLength;
messageData[1] = (byte)(messageLength >> 8);
messageData[2] = (byte)(messageLength >> 16);
messageData[3] = (byte)(messageLength >> 24);
Array.Copy(message, 0, messageData, 4, messageLength);
// Zero pad the end of the array
for (int i = (messageLength + 4); i < encodedLength; i++)
messageData[i] = 0;
// Loop through the message encrypting it a block at a time
for (int i = 0; i < encodedLength; i += (nb * 4))
{
Array.Copy(messageData, i, dataBlock, 0, (nb * 4));
// Do some XORing if in CBC mode
if (cryptMode == EncryptionMode.ModeCBC)
for (int j = 0; j < (nb * 4); j++)
dataBlock[j] ^= vectorBlock[j];
encrypt(dataBlock);
if (cryptMode == EncryptionMode.ModeCBC)
Array.Copy(dataBlock, 0, vectorBlock, 0, dataBlock.Length);
Array.Copy(dataBlock, 0, messageData, i, (nb * 4));
}
return messageData;
}
/// <summary>This version of EncryptData takes the message, password
/// and IV as strings and encrypts the message, returning the encrypted text as a string.
/// </summary>
/// <param name="message">The plain text message</param>
/// <param name="password">The password/key to encrypt the message with</param>
/// <param name="initialisationVector">The IV as a string</param>
/// <param name="blockSize">The block size used to encrypt the message</param>
/// <param name="keySize">The key size used to encrypt the message</param>
/// <param name="cryptMode">The encryption mode, CBC or ECB, used to encrypt the message</param>
/// <param name="returnAsHex">Whether the encrypted message is to be returned as Hex</param>
public static string EncryptData(string message, string password,
string initialisationVector, BlockSize blockSize,
KeySize keySize, EncryptionMode cryptMode, bool returnAsHex)
{
byte[] messageData, passwordData, vectorData;
// If message is empty dont bother doing any work
if (message.Length <= 0)
return "";
System.Text.UnicodeEncoding encoderUnicode = new System.Text.UnicodeEncoding();
// Convert message, key and IV to byte arrays
messageData = encoderUnicode.GetBytes(message);
passwordData = encoderUnicode.GetBytes(password);
vectorData = encoderUnicode.GetBytes(initialisationVector);
// Return encrypted message as string (hex version of bytes if required)
if (returnAsHex)
return BytesToHex(EncryptData(messageData, passwordData,
vectorData, blockSize, keySize, cryptMode));
else
return encoderUnicode.GetString(EncryptData(messageData, passwordData,
vectorData, blockSize, keySize, cryptMode));
}
/// <summary>This version of DecryptData takes the encrypted message, password
/// and IV as byte arrays and decrypts the message, returning the plain text as
/// a byte array.
/// </summary>
/// <param name="message">The encrypted message</param>
/// <param name="password">The password/key that was used to encrypt the message</param>
/// <param name="initialisationVector">The IV</param>
/// <param name="blockSize">The block size used in encrypting the message</param>
/// <param name="keySize">The key size used in encrypting the message</param>
/// <param name="cryptMode">The encryption mode, CBC or ECB, used in encrypting the message</param>
public static byte[] DecryptData(byte[] message, byte[] password,
byte[] initialisationVector, BlockSize blockSize,
KeySize keySize, EncryptionMode cryptMode)
{
byte[] messageData, keyBlock, vectorBlock, dataBlock;
int messageLength, encodedLength, nb, nk;
// Dont do any work if message is empty
encodedLength = message.Length;
if (encodedLength <= 0)
return message;
// Set up arrays based on block size
switch (blockSize)
{
case BlockSize.Block128:
nb = 4;
break;
case BlockSize.Block192:
nb = 6;
break;
default: // assume 256
nb = 8;
break;
}
vectorBlock = new byte[nb * 4];
dataBlock = new byte[nb * 4];
for (int i = 0; i < (nb * 4); i++)
{
vectorBlock[i] = 0;
dataBlock[i] = 0;
}
// Set up array based on key size
switch (keySize)
{
case KeySize.Key128:
nk = 4;
break;
case KeySize.Key192:
nk = 6;
break;
default: // assume 256
nk = 8;
break;
}
keyBlock = new byte[nk * 4];
for (int i = 0; i < (nk * 4); i++)
{
keyBlock[i] = 0;
}
// Key will be zero padded, or trimmed to correct size
for (int i = 0; (i < password.Length) && (i < (nk * 4)); i++)
keyBlock[i] = password[i];
// Vector will be zero padded, or trimmed to correct size
for (int i = 0; (i < initialisationVector.Length) && (i < (nb * 4)); i++)
vectorBlock[i] = initialisationVector[i];
// Prepare the key and tables using the Rijndael fuinctions
gentables();
gkey(nb, nk, keyBlock);
// Decrypt a block at a time
for (int i = 0; i < encodedLength; i += (nb * 4))
{
Array.Copy(message, i, dataBlock, 0, (nb * 4));
decrypt(dataBlock);
// If CBC mode we need to do some extra XORing
if (cryptMode == EncryptionMode.ModeCBC)
{
for (int j = 0; j < (nb * 4); j++)
dataBlock[j] ^= vectorBlock[j];
Array.Copy(message, i, vectorBlock, 0, (nb * 4));
}
Array.Copy(dataBlock, 0, message, i, (nb * 4));
}
// Message length was originally put on front of message, so retrieve it
messageLength = (int)message[0] | (((int)message[1]) << 8) |
(((int)message[2]) << 16) | (((int)message[3]) << 24);
// Get the original message from the clear text
messageData = new byte[messageLength];
Array.Copy(message, 4, messageData, 0, messageLength);
return messageData;
}
/// <summary>This version of DecryptData takes the encrypted message, password
/// and IV as strings and decrypts the message, returning the plain text as a string.
/// </summary>
/// <param name="message">The encrypted message</param>
/// <param name="password">The password/key that was used to encrypt the message</param>
/// <param name="initialisationVector">The IV as a string</param>
/// <param name="blockSize">The block size used in encrypting the message</param>
/// <param name="keySize">The key size used in encrypting the message</param>
/// <param name="cryptMode">The encryption mode, CBC or ECB, used in encrypting the message</param>
/// <param name="messageAsHex">Whether the encrypted message was returned as Hex</param>
public static string DecryptData(string message, string password,
string initialisationVector, BlockSize blockSize,
KeySize keySize, EncryptionMode cryptMode, bool messageAsHex)
{
byte[] messageData, passwordData, vectorData;
// Dont do any work is the message is empty
if (message.Length <= 0)
return "";
System.Text.UnicodeEncoding encoderUnicode = new System.Text.UnicodeEncoding();
// Was message supplied in Hex or as simple string
if (messageAsHex)
messageData = HexToBytes(message);
else
messageData = encoderUnicode.GetBytes(message);
// Convert key and IV to byte arrays
passwordData = encoderUnicode.GetBytes(password);
vectorData = encoderUnicode.GetBytes(initialisationVector);
// Return the decrypted plain test as a string
return encoderUnicode.GetString(DecryptData(messageData, passwordData,
vectorData, blockSize, keySize, cryptMode));
}
/// <summary>Utility function to convert a byte array to a string</summary>
public static string BytesToString(byte[] message)
{
if (message.Length <= 0)
return "";
System.Text.UnicodeEncoding encoderUnicode = new System.Text.UnicodeEncoding();
return encoderUnicode.GetString(message);
}
/// <summary>Utility function to convert a string to a byte array</summary>
public static byte[] StringToBytes(string message)
{
if (message.Length <= 0)
return new byte[0];
System.Text.UnicodeEncoding encoderUnicode = new System.Text.UnicodeEncoding();
return encoderUnicode.GetBytes(message);
}
/// <summary>Utility function to convert a byte array to a string of hex</summary>
public static string BytesToHex(byte[] message)
{
System.Text.StringBuilder temp = new System.Text.StringBuilder();
// Convert each byte to hex and add to string
for (int i = 0; i < message.Length; i++)
temp.Append(string.Format("{0:X2}", message[i]));
return temp.ToString();
}
/// <summary>Utility function to convert a string of hex to a byte array</summary>
public static byte[] HexToBytes(string message)
{
// Strip non hex
message = System.Text.RegularExpressions.Regex.Replace(message.ToUpper(), "[^0-9A-F]", "");
// Prepare return array
byte[] data = new byte[message.Length / 2];
// Convert hex character pairs to bytes
for (int i = 0; i < message.Length; i += 2)
{
data[i / 2] = (Convert.ToByte(message.Substring(i, 2), 16));
}
return data;
}
}
}
@MalekGG
Copy link

MalekGG commented Nov 19, 2015

Please i need help. I am working on a site using ASP CLASSIC and have to use rijndael to encrypt and decrypt some data. I download this http://www.freevbcode.com/ShowCode.asp?ID=2389
But i decrypt i don't have the result required. i have something like this �A�í] �§m&�æ�ö�$â�¤¼¶5:,¾¶£��* �
Can you tell me what can be the error please?

@Dattuwak
Copy link

Can you tell me how to use this code? This source code is easy and better to understand but please provide the proper explanation. Still, I work on how to make a simple calculator in visual basic 6.0 and I refer to this website for better understanding. can you provide the explanation like that website.

@ryno1234
Copy link
Author

@Dattuwak, are you trying to do encryption / decryption within your calculator app? And are you trying to encrypt data in .Net and decrypt it in ASP / VB (or vice versa)?

@zamu85
Copy link

zamu85 commented Jan 11, 2022

Hi, I need some help on decrypting text. I have a string encrypted with Japanese character but the code you provide convert only HexNumber.
How can I have plain text after decrypt?
Thanks

@ryno1234
Copy link
Author

@zamu85, what is the code that you're using currently. Can you give an example of a full encrypt / decrypt?

@zamu85
Copy link

zamu85 commented Jan 11, 2022

I've the encrypted string generated from Visual Basic.
In c# I use this method

public string DecryptDataW(string encryptedMessage, string password) { if (encryptedMessage.Length % 2 == 1) throw new Exception("The binary key cannot have an odd number of digits"); var result = Rijndael.DecryptData(encryptedMessage, password, "", Rijndael.BlockSize.Block256, Rijndael.KeySize.Key256, Rijndael.EncryptionMode.ModeECB, false ); return result; }

where encryptedMessage contains the string with japanese characters

@ryno1234
Copy link
Author

ryno1234 commented Jan 11, 2022

@zamu85, it has been years since I've used this code and I don't have it running on my machine at the moment, but my suggestion would be to call, from C# AspRijndael.DecryptData() instead and then change the final line of that code in that method to Encoding.Unicode.GetString(result); instead of ASCIIEncoding.ASCII.GetString(result);.

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