Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

Dattuwak commented Oct 11, 2021

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

ryno1234 commented Oct 11, 2021

@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

ryno1234 commented Jan 11, 2022

@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