-
-
Save ryno1234/ea34415643d109974b6f to your computer and use it in GitHub Desktop.
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: [email protected] | |
/// 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; | |
} | |
} | |
} |
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.
@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)?
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
@zamu85, what is the code that you're using currently. Can you give an example of a full encrypt / decrypt?
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
@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);
.
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?