Getting AES PHP & C# To Match - c#

I've seen a few posts about this, but yet I can't seem to get this to work, any ideas?
RESULTS:
C# Encrypted string test = O6qzYiLPCpbXUf8PjMHpcg==
php Encrypted string test = SdS1dN1ugyAVYGFzHiTayg==
C# Code
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
string enctext = EncryptString("test", "qwertyuiopasdfghjklzxcvbnmqwerty", _"1234567890123456");
PHP
function aesenc($message, $keystring, $ivstring){
$IV_UTF = mb_convert_encoding($ivstring, 'UTF-8');
$KEY_UTF = mb_convert_encoding($keystring, 'UTF-8');
return base64_encode( mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $KEY_UTF, $message, MCRYPT_MODE_CBC, $IV_UTF));
}
$enctext = aesenc("test", "qwertyuiopasdfghjklzxcvbnmqwerty", _"1234567890123456");

Found the answer, needed to add padding to the $message in php
function aesenc($message, $keystring, $ivstring){
$IV_UTF = mb_convert_encoding($ivstring, 'UTF-8');
$KEY_UTF = $keystring;
return base64_encode( mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $KEY_UTF, addpadding($message), MCRYPT_MODE_CBC, $IV_UTF));
}
function addpadding($string, $blocksize = 16)
{
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}

Related

Encrypt in C# Decrypt AES CBC 256

I want encrypt in C# and decrypt in c++ but I have some Encoding problem :
example variables :
Key : gOtIPaLver—vS5UAnJbPqsDZSf,yJ1
IVString : gOtIPaLver—vS5
my c# code :
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString.Substring(0,32));
byte[] IV = UTF8Encoding.UTF8.GetBytes(IVString);
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
rj.Padding = PaddingMode.PKCS7;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
When I try encrypt and my Key have some not ASCII char - count of bytes is more than lenght of string .
How Encoding I shound use ? In C++ I use EVP (default padding is PKCS7) .
static string decryptEX(string KS, string ctext)
{
EVP_CIPHER_CTX* ctx;
ctx = EVP_CIPHER_CTX_new();
string IV = KS.substr(0, 16);
int rc = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (byte*)&KS[0], (byte*)&IV[0]);
std::string rtext;
rtext.resize(ctext.size());
int out_len1 = (int)rtext.size();
rc = EVP_DecryptUpdate(ctx, (byte*)&rtext[0], &out_len1, (const byte*)&ctext[0], (int)ctext.size());
int out_len2 = (int)rtext.size() - out_len1;
rc = EVP_DecryptFinal_ex(ctx, (byte*)&rtext[0] + out_len1, &out_len2);
try
{
rtext.resize(out_len1 + out_len2);
}
catch (exception e)
{
}
return rtext;
}
Your call to
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString.Substring(0,32));
fails because there are not 32 characters in that string. Yes, there would be 32 bytes if the string is encoded as UTF8. But Substring takes a count of characters.
Changing that line to
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);
gives a 32-byte long key.
Since you can't count on getting proper input for the KeyString, you could validate after this point that your key length is long enough.
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString);
if (Key.Length < 32)
throw new KeyLengthException("some useful info as to why this was thrown"); // or some other appropriate Exception type you create or resuse.
If I'm correct in assuming which key, IV, and block sizes you require, this should do what you need:
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = UTF8Encoding.UTF8.GetBytes(KeyString).Take(32).ToArray();
if (Key.Length < 32)
throw new Exception("KeyString not at least 32 bytes.");
byte[] IV = UTF8Encoding.UTF8.GetBytes(IVString).Take(16).ToArray();
if (Key.Length < 32)
throw new Exception("IVString not at least 16 bytes.");
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.KeySize = 128;
rj.BlockSize = 128;
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
rj.Padding = PaddingMode.PKCS7;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}

Secure Encrypt Decrypt Algurithm can use for Android,C#,PHP,iPhone

I'm going to encrypt my data transferring between my multi platform apps. My question is that which algorithm can be used that work for all these platforms?
That should have these parameters:
Dynamic key and iv.
Supported in C#, Android, Swift, PHP.
Be secure enough.
It will be welcome if anybody give me some samples or links for each platform.
UPDATE:
I tried these classes:
Android:
public class Cryptor {
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public Cryptor(byte[] key_par,byte[] iv_par)
{
keyspec = new SecretKeySpec(key_par, "AES");
ivspec = new IvParameterSpec(iv_par);
try {
cipher = Cipher.getInstance("AES/CBC/ZeroPadding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public byte[] encrypt(byte[] input) throws Exception
{
if(text == null || text.length() == 0)
throw new Exception("Empty input");
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(input);
} catch (Exception e)
{
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0)
throw new Exception("Empty string");
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e)
{
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
public static String bytesToHex(byte[] data)
{
if (data==null)
{
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++) {
if ((data[i]&0xFF)<16)
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
public static byte[] hexToBytes(String str) {
if (str==null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i=0; i<len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
}
return buffer;
}
}
}
PHP:
class MCrypt
{
protected $in_iv;
protected $in_key;
function __construct($in_key , $in_iv)
{
$this->key = $in_key;
$this->iv = $in_iv;
}
function encrypt($str) {
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return bin2hex($encrypted);
}
function decrypt($code) {
$code = $this->hex2bin($code);
$iv = $this->iv;
$td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv);
mcrypt_generic_init($td, $this->key, $iv);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return utf8_encode(trim($decrypted));
}
protected function hex2bin($hexdata) {
$bindata = '';
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
}
C#:
class Cryptor
{
private byte[] iv;
private byte[] key;
public Cypher(byte[] key, byte[] iv)
{
this.key = key;
this.iv = iv;
}
public byte[] EncryptRJ128(byte[] input)
{
var encoding = new UTF8Encoding();
byte[] encrypted;
using (var rj = new RijndaelManaged())
{
try
{
rj.Padding = PaddingMode.Zeros;
rj.Mode = CipherMode.CBC;
rj.KeySize = 128;
rj.BlockSize = 128;
rj.Key = key;
rj.IV = iv;
var ms = new MemoryStream();
var cs = new CryptoStream(ms, rj.CreateEncryptor(key, iv), CryptoStreamMode.Write);
var sr = new StreamWriter(cs);
sr.Write(input);
sr.Flush();
cs.FlushFinalBlock();
encrypted = ms.ToArray();
}
finally
{
rj.Clear();
}
}
return encrypted;
}
public String DecryptRJ128(byte[] input)
{
var sRet = "";
var encoding = new UTF8Encoding();
using (var rj = new RijndaelManaged())
{
try
{
rj.Padding = PaddingMode.Zeros;
rj.Mode = CipherMode.CBC;
rj.KeySize = 128;
rj.BlockSize = 128;
rj.Key = key;
rj.IV = iv;
var ms = new MemoryStream(input);
var cs = new CryptoStream(ms, rj.CreateDecryptor(key, iv), CryptoStreamMode.Read);
var sr = new StreamReader(cs);
sRet = sr.ReadLine();
}
finally
{
rj.Clear();
}
}
return sRet;
}
}
TEST:
This is some example that I used to test:
key ={ 106,104,103,97,103,94,115,106,102,96,115,53,53,52,55,53}
iv ={104,49,52,56,114,102,103,49,48,50,52,97,56,51,118,52}
input ={57,102,117,105,65,75,113,105,108,119,113,54,109,73,89,104}
Now trying to encrypt:
Android and PHP output:
170, 29, 170, 139, 14, 192, 81, 232, 41, 237, 25, 19, 130, 237, 15, 198
c# OUTPUT:
59 , 85 , 127 , 29 , 161 , 145 , 23 , 127 , 246 , 100 , 157 , 234 , 128 , 65

TripleDES encription not getting same results in c# and PHP

C# returns the following base64 encoded string:
joxzS5XnP63ymrhy6t4ogWK9TxwfwD83
below is the code in c#
us
ing System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
class Program
{
static void Main()
{
// Read in every line in the file.
using (StreamReader reader = new StreamReader("input.txt"))
{
string abc = "string to encrypt";
Program p = new Program();
string value = p.Encrypt(abc, true);
Console.Write(value);
}
}
public string Encrypt(string toEncrypt, bool useHashing)
{
byte[] keyArray;
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
//System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
// Get the key from config file
string key = "encrypt key";
//System.Windows.Forms.MessageBox.Show(key);
if (useHashing)
{
MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
hashmd5.Clear();
}
else
keyArray = UTF8Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
tdes.Key = keyArray;
tdes.Mode = CipherMode.ECB;
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
tdes.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
}
I am using MCrypt library in PHP which returns
ThPKJ1BPJLeUwJtIT/zAs3ocZ2s6SU+M
PHP code:
$str = "string to encrypt";
$input = utf8_encode($str);
$key = "encrypt key";
echo apiEncode($input, $key);
function apiEncode($data, $secret)
{
//Generate a key from a hash
$key = md5(utf8_encode($secret), true);
//Create init vector
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ecb), MCRYPT_RAND);
//Pad for PKCS7
$blockSize = mcrypt_get_block_size('tripledes', 'ecb');
$len = strlen($data);
$pad = $blockSize - ($len % $blockSize);
$data .= str_repeat(chr($pad), $pad);
//Encrypt data
$encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb'); //, $iv);
return base64_encode($encData);
}
apart from the above I have tried various other solutions found at so
tripledes encryption not yielding same results in PHP and C#
TripleDES Encrypting in C# and PHP not coming out the same (PKCS7, ECB)?
Your C# code does not set an IV, thus your IV will be a block of zeroes. I do not know PHP, but I strongly suspect that mcrypt_create_iv() creates a non-trivial IV.
Apart from that, you should consider CBC-mode instead of ECB-mode.
Considering the Security vulnerabilities of DES and TripleDES, implemented AES/RIJNDAEL_256 algo at both the sides.
C#
public String DecryptRJ256(string cypher, string KeyString, string IVString)
{
string sRet = string.Empty;
RijndaelManaged rj = new RijndaelManaged();
UTF8Encoding encoding = new UTF8Encoding();
byte[] decbuff = Convert.FromBase64String(cypher);
try
{
byte[] Key = encoding.GetBytes(KeyString);
byte[] IV = encoding.GetBytes(IVString);
rj.Padding = PaddingMode.PKCS7;
rj.Mode = CipherMode.CBC;
rj.KeySize = 256;
rj.BlockSize = 256;
rj.Key = Key;
rj.IV = IV;
MemoryStream ms = new MemoryStream(decbuff);
using (CryptoStream cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
sRet = sr.ReadToEnd();
}
}
}
finally
{
rj.Clear();
}
return sRet;
}
public string Encrypt(string message, string KeyString, string IVString)
{
byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.BlockSize = 256;
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
PHP
public function apiEncode($text, $key, $iv)
{
// to append string with trailing characters as for PKCS7 padding scheme
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding = $block - (strlen($text) % $block);
$text .= str_repeat(chr($padding), $padding);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
return base64_encode($crypttext);
}
publc function apiDecode($text, $key, $iv){
$text = base64_decode($text);
$crypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
return $crypttext;
}

Rijndael 256 Encrypt/decrypt between c# and php?

UPDATED
I have made the changes to the C# code so it uses a block size of 256. but now the hello world looks like this http://pastebin.com/5sXhMV11 and I cant figure out what I should use with rtrim() to get ride of the mess at the end.
Also when you say the IV should be random, by this do you mean don't use the same IV more then once or is the way I have coded it wrong?
Thanks again!
Hi,
I'm trying to decrypt a string with PHP that was encrypted in C#. I can't seem to get PHP to decrypt it using mcrypt and could do with some help please. I get the following error with php so I am guessing I'm not setting the IV correctly.
Error: The IV parameter must be as long as the blocksize
Both functions use the same cipher, key, IV and set to CBC mode:
encrypted text from c# = UmzUCnAzThH0nMkIuMisqg==
key 32 long = qwertyuiopasdfghjklzxcvbnmqwerty
iv 16 long = 1234567890123456
C#
public static string EncryptString(string message, string KeyString, string IVString)
{
byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);
string encrypted = null;
RijndaelManaged rj = new RijndaelManaged();
rj.Key = Key;
rj.IV = IV;
rj.Mode = CipherMode.CBC;
try
{
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
sw.Close();
}
cs.Close();
}
byte[] encoded = ms.ToArray();
encrypted = Convert.ToBase64String(encoded);
ms.Close();
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
rj.Clear();
}
return encrypted;
}
PHP
var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
var $mcrypt_mode = MCRYPT_MODE_CBC;
function decrypt($key, $iv, $encrypted)
{
$encrypted = base64_decode($encrypted);
$decrypted = rtrim(mcrypt_decrypt($this->mcrypt_cipher, $key, $encrypted, $this->mcrypt_mode, $iv), "\0");;
return $decrypted;
}
Thanks
If you want to use Rijndael256 in your C# application you have to set the BlockSize to 256.
RijndaelManaged rj = new RijndaelManaged();
rj.BlockSize = 256;
And then your iv has to be 256 bits long as well.
see SymmetricAlgorithm.BlockSize Property
Or the other way round: Currently your C# application uses Rijndael128 and so must your php script.
<?php
class Foo {
protected $mcrypt_cipher = MCRYPT_RIJNDAEL_128;
protected $mcrypt_mode = MCRYPT_MODE_CBC;
public function decrypt($key, $iv, $encrypted)
{
$iv_utf = mb_convert_encoding($iv, 'UTF-8');
return mcrypt_decrypt($this->mcrypt_cipher, $key, base64_decode($encrypted), $this->mcrypt_mode, $iv_utf);
}
}
$encrypted = "UmzUCnAzThH0nMkIuMisqg==";
$key = "qwertyuiopasdfghjklzxcvbnmqwerty";
$iv = "1234567890123456";
$foo = new Foo;
echo $foo->decrypt($key, $iv, $encrypted);
prints hello world
Encrypt using PHP;
/Generate public key for encrytion
$path = "keys/";
$crt = openssl_x509_read(file_get_contents($path."cert.crt"));
$publickey = openssl_get_publickey($crt);
//Encrypt using public key
openssl_public_encrypt($source, $crypted, $publickey);
//openssl_private_encrypt($source, $crypted, $privkey);
echo base64_encode($crypted);
Decrypt using C#
X509Certificate2 x509cert = new X509Certificate2(pKeyFilename);
RSACryptoServiceProvider.UseMachineKeyStore = false;
RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)x509cert.PrivateKey;
byte[] decrypted = crypt.Decrypt(Convert.FromBase64String(data), false);
return ASCIIEncoding.UTF8.GetString(decrypted);
where pKeyFilename is a Personal Information Exchange File created with the certificate file cert.crt. This examples uses a AES-256 encryption.

Problem using AES and base64_encode the result

I am trying to encrypt a string then covert it into a base64_encode string to be passed to a website so that it can decrypt it.
My functions below dont seem to be working correctly and it won't decrypt the base64_encode string back to the original string.
Anyone see the problem?
Thanks
public static string EncryptToString(string data, string KeyString, string IVString)
{
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] Data = encoding.GetBytes(data);
byte[] Key = encoding.GetBytes(KeyString);
byte[] IV = encoding.GetBytes(IVString);
try
{
MemoryStream fStream = new MemoryStream(Data);
// Set Rijndael object mode.
Rijndael RijndaelAlg;
RijndaelAlg = Rijndael.Create();
RijndaelAlg.Mode = CipherMode.CBC;
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
RijndaelAlg.CreateEncryptor(Key, IV),
CryptoStreamMode.Read);
// Create a StreamReader using the CryptoStream.
StreamReader sReader = new StreamReader(cStream);
string encryptedString = null;
try
{
// Read the data from the stream
// to decrypt it.
encryptedString = sReader.ReadToEnd();
// Convert result into a base64-encoded string.
byte[] bytes = encoding.GetBytes(encryptedString);
encryptedString = Convert.ToBase64String(bytes, 0, bytes.Length);
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sReader.Close();
cStream.Close();
fStream.Close();
RijndaelAlg.Dispose();
}
// Return the string.
return encryptedString;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
}
public static string DecryptToString(string data, string KeyString, string IVString)
{
ASCIIEncoding encoding = new ASCIIEncoding();
// Convert result from a base64-encoded to string.
byte[] Data = Convert.FromBase64String(data);
byte[] Key = encoding.GetBytes(KeyString);
byte[] IV = encoding.GetBytes(IVString);
try
{
MemoryStream fStream = new MemoryStream(Data);
// Set Rijndael object mode.
Rijndael RijndaelAlg;
RijndaelAlg = Rijndael.Create();
RijndaelAlg.Mode = CipherMode.CBC;
// Create a CryptoStream using the FileStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream(fStream,
RijndaelAlg.CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// Create a StreamReader using the CryptoStream.
StreamReader sReader = new StreamReader(cStream);
string decryptedString = null;
try
{
// Read the data from the stream
// to decrypt it.
decryptedString = sReader.ReadToEnd();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: {0}", e.Message);
}
finally
{
// Close the streams and
// close the file.
sReader.Close();
cStream.Close();
fStream.Close();
RijndaelAlg.Dispose();
}
// Return the string.
return decryptedString;
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine("A file error occurred: {0}", e.Message);
return null;
}
}
I'm not sure exactly where it is going wrong, but when I was doing this I had some strange issues too. I'll share with you the code I wrote to get this working properly:
static public String EncryptString(String message)
{
String sRet = "";
RijndaelManaged rj = new RijndaelManaged();
try
{
rj.Key = Key;
rj.IV = IV;
MemoryStream ms = new MemoryStream();
using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(message);
}
}
byte[] encoded = ms.ToArray();
sRet = Convert.ToBase64String(encoded);
}
finally
{
rj.Clear();
}
return sRet;
}
static public String DecryptString(String cypher)
{
String sRet = "";
RijndaelManaged rj = new RijndaelManaged();
try
{
byte[] message = Convert.FromBase64String(cypher);
rj.Key = Key;
rj.IV = IV;
MemoryStream ms = new MemoryStream(message);
using (CryptoStream cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
sRet = sr.ReadToEnd();
}
}
}
finally
{
rj.Clear();
}
return sRet;
}
Key and IV are static byte[] contained in the class.

Categories