I'm using the following code to decrypt some strings I reicive but I'm getting the following error: BlockSize must be 128 in this implementation.
I would like to know if there is any way and how it would be possible to decrypt the strings I get without decreasing the size since I can't change my key and IV because the strings were encrypted with then.
private string Decrypt(string text)
{
var inputByteArray = Convert.FromBase64String(text);
var rm = new RijndaelManaged();
rm.BlockSize = 256;
rm.IV = Encoding.UTF8.GetBytes("11111111111111111111111111111111");
rm.KeySize = 256;
rm.Key = new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes("11111111-1111-1111-1111-111111111111"));
var decryptor = rm.CreateDecryptor();
var msDecrypt = new MemoryStream(inputByteArray);
var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
var srDecrypt = new StreamReader(csDecrypt);
return srDecrypt.ReadToEnd();
}
I'm using .netcore 5
to solve this problem i followed Topaco suggestion and used the BouncyCastle/C# library and that solved the error i was getting, below I leave the solution I used based on other forums.
public static string Decrypt(string cipherText)
{
var ivStringBytes = Encoding.UTF8.GetBytes("11111111111111111111111111111111");
var cipherTextBytes = Convert.FromBase64String(cipherText);
var keyBytes = new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes("11111111-1111-1111-1111-111111111111"));
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(false, keyParamWithIV);
var finalBytes = cipher.DoFinal(cipherTextBytes);
var final = Encoding.UTF8.GetString(finalBytes);
return final;
}
And this is the package that i used:
<PackageReference Include="BouncyCastle.NetCore" Version="1.8.10" />
Related
I need to implement AES encryption in 2 different projects, but one must use the .NET standard crypto libraries and the other must use BouncyCastle. Both are C# code. Relevant methods are as follows:
.NET:
internal class NETAesCryptor : IAesCryptor
{
public Tuple<byte[], byte[]> Encrypt(string plaintext, byte[] key)
{
byte[] ciphertext, iv;
using (var aes_provider = new AesCryptoServiceProvider())
{
aes_provider.Padding = PaddingMode.PKCS7;
aes_provider.GenerateIV();
iv = aes_provider.IV;
var encryptor = aes_provider.CreateEncryptor(key, iv);
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (var sw = new StreamWriter(cs))
{
sw.Write(plaintext);
}
ciphertext = ms.ToArray();
}
}
}
var result = new Tuple<byte[], byte[](ciphertext, iv);
return result;
}
public string Decrypt(byte[] ciphertext, byte[] iv, byte[] key)
{
string plaintext;
using (var aes_provider = new AesCryptoServiceProvider())
{
aes_provider.Padding = PaddingMode.PKCS7;
aes_provider.IV = iv;
var decryptor = aes_provider.CreateDecryptor(key, iv);
using (var ms = new MemoryStream(ciphertext))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
plaintext = sr.ReadToEnd();
}
}
}
}
return plaintext;
}
}
Bouncycastle:
internal class BCAesCryptor : IAesCryptor
{
private SecureRandom _r;
public BCAesCryptor()
{
_r = new SecureRandom();
}
public Tuple<byte[], byte[]> Encrypt(string plaintext, byte[] key)
{
var plaintext_bytes = Encoding.UTF8.GetBytes(plaintext);
var iv = GenerateRandomBytes(16);
var engine = new AesEngine();
var cbc_cipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(cbc_cipher, new Pkcs7Padding());
var key_param = new KeyParameter(key);
var key_param_with_iv = new ParametersWithIV(key_param, iv);
cipher.Init(true, key_param_with_iv);
var ciphertext = new byte[cipher.GetOutputSize(plaintext_bytes.Length)];
var length = cipher.ProcessBytes(plaintext_bytes, ciphertext, 0);
cipher.DoFinal(ciphertext, length);
var result = new Tuple<byte[], byte[]>(ciphertext, iv);
return result;
}
public string Decrypt(byte[] ciphertext, byte[] iv, byte[] key)
{
var engine = new AesEngine();
var cbc_cipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(cbc_cipher, new Pkcs7Padding());
var key_param = new KeyParameter(key);
var key_param_with_iv = new ParametersWithIV(key_param, iv);
cipher.Init(false, key_param_with_iv);
var plaintext = new byte[cipher.GetOutputSize(ciphertext.Length)];
var length = cipher.ProcessBytes(ciphertext, plaintext, 0);
cipher.DoFinal(plaintext, length);
var result = Encoding.UTF8.GetString(plaintext);
return result;
}
private byte[] GenerateRandomBytes(int length = 16)
{
var result = new byte[length];
_r.NextBytes(result);
return result;
}
}
Encryption/decryption between .NET methods works OK, and Bouncycastle encryption/.NET decryption also works OK. But for some reason, Bouncycastle decryption adds a variable number of \0 characters at the end of the plaintext, and I don't know why is this happening.
Test code I'm using:
[TestClass]
public class AesCryptorTests
{
private byte[] _key;
private string _plaintext;
public AesCryptorTests()
{
_key = GenerateRandomBytes();
_plaintext = "Lorem ipsum dolor sit amet";
}
[TestMethod]
public void TestMethod2()
{
var bc = new BCAesCryptor();
var net = new NETAesCryptor();
var result = net.Encrypt(_plaintext, _key);
var new_plaintext = bc.Decrypt(result.Ciphertext, result.IV, _key);
Assert.AreEqual(_plaintext, new_plaintext);
}
private byte[] GenerateRandomBytes(int cantidad = 16)
{
var result = new byte[cantidad];
using (var r = new RNGCryptoServiceProvider())
{
r.GetBytes(result);
}
return result;
}
}
In the previous test, the decryption returns Lorem ipsum dolor sit amet\0\0\0\0\0\0 instead of the plaintext.
Any advice/comment would be greatly appreciated.
The Bouncy Castle can only guess the output size of the plaintext message in advance during the call to GetOutputSize. It cannot know how many padding bytes are used, because those are only available after decryption. So they would have to partially decrypt the ciphertext to know the amount of padding, and that's taking it a step too far. Therefore you get just an estimate on the high side so that the maximum number of bytes can still fit in your newly created buffer.
You'll need the return value of the ProcessBytes and DoFinal to see the actual number of bytes that are decrypted from the ciphertext (in the input buffer and internal buffer) when the methods are called. DoFinal decrypts the last block(s) and then removes the padding from the final block, so only at that time is the size of the (remaining) plaintext known.
What you're currently seeing as zero valued bytes are just the unused bytes of the buffer, as the plaintext size is smaller than the value returned by GetOutputSize.
Of course, this is all hidden in the streaming code of the .NET sample, where ReadToEnd is required to doing some advanced buffering (probably using a MemoryStream internally itself).
Following instructions from Maarten Bodewes, the final working code is as follows:
public string Decrypt(byte[] ciphertext, byte[] iv, byte[] key)
{
var engine = new AesEngine();
var cbc_cipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(cbc_cipher, new Pkcs7Padding());
var key_param = new KeyParameter(key);
var key_param_with_iv = new ParametersWithIV(key_param, iv);
cipher.Init(false, key_param_with_iv);
var decryption_buffer = new byte[cipher.GetOutputSize(ciphertext.Length)];
var initial_length = cipher.ProcessBytes(ciphertext, decryption_buffer, 0);
var last_bytes = cipher.DoFinal(decryption_buffer, initial_length);
var total_bytes = initial_length + last_bytes;
var plaintext = new byte[total_bytes];
Array.Copy(decryption_buffer, plaintext, total_bytes);
var result = Encoding.UTF8.GetString(plaintext);
return result;
}
Note that the length of the plaintext is now calculated with the integer outputs of the decryption methods, and a simple array copy is able to create a plaintext without extra characters.
I need to decrypt a string in C# that was encrypted via CakePHP's Security::rijndael library.
The string is being encrypted in PHP like this:
base64_encode(Security::rijndael($pw, Configure::read('SecretKey'), 'encrypt'))
The resulting encoding is 88 characters long and stored in the db.
Here is how I'm trying to decrypt it in C#:
public static string Decrypt(string encode, string secretKey)
{
var sha = SHA256Managed.Create();
var saltBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(secretKey));
var key = new Rfc2898DeriveBytes(secretKey, saltBytes);
var rm = new RijndaelManaged();
rm.Mode = CipherMode.CBC;
rm.KeySize = 256;
rm.BlockSize = 256;
rm.Key = key.GetBytes(rm.KeySize / 8);
rm.IV = key.GetBytes(rm.BlockSize / 8);
var decryptor = rm.CreateDecryptor(rm.Key, rm.IV);
var cipher = Convert.FromBase64String(encode);
string decrypted;
using (var msDescrypt = new MemoryStream(cipher))
{
using (var csDescrypt = new CryptoStream(msDescrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDescrypt = new StreamReader(csDescrypt))
{
decrypted = srDescrypt.ReadToEnd();
}
}
}
return decrypted;
}
When reading the stream I get an exception of "Length of the data to decrypt is invalid". Do I need to manipulate the incoming encoded string to make this work?
I use this example from stackoverflow :
C# Encryption to PHP Decryption
GENERATE FUNCTION :
public static void GenerateKeyIV(out string key, out string IV)
{
var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};
key = Convert.ToBase64String(rj.Key);
IV = Convert.ToBase64String(rj.IV);
}
Encrypt 2 FUNCTION :
public static string Encrypt2(string prm_text_to_encrypt, string prm_key, string prm_iv)
{
var sToEncrypt = prm_text_to_encrypt;
var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};
var key = Encoding.ASCII.GetBytes(prm_key);
var IV = Encoding.ASCII.GetBytes(prm_iv);
//var key = Convert.FromBase64String(prm_key);
//var IV = Convert.FromBase64String(prm_iv);
var encryptor = rj.CreateEncryptor(key, IV);
var msEncrypt = new MemoryStream();
var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt);
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();
var encrypted = msEncrypt.ToArray();
return (Convert.ToBase64String(encrypted));
}
MAIN PROGRAM :
Enc2.GenerateKeyIV(out key, out iv);
string encrypted_url = Enc2.Encrypt2("test tekst todo",key,iv);
Console.WriteLine(encrypted_url);
==> iv = cCJNWmwOtIBg6zM7Mz/JQV/lcauNMWf50nQk1ZiEKZ4=
==> key = gNDiEqWk7aGhj1+A2EURW5CPurxHPcfy3F2FTa4peC0=
==> System.Security.Cryptography.CryptographicException: Specified initialization vector (IV) does not match the block size for this algorithm.
==> the key and iv seem to be properly generated, I dont understand why I receive this error.
Check your encryption method Enc2.Encrypt2(). It may be using a different block size from what you specified in your IV generation method.
UPDATE:
Do this:
public static string Encrypt2(string prm_text_to_encrypt, string prm_key, string prm_iv)
{
var sToEncrypt = prm_text_to_encrypt;
var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};
var key = Convert.FromBase64String(prm_key);
var IV = Convert.FromBase64String(prm_iv);
var encryptor = rj.CreateEncryptor(key, IV);
var msEncrypt = new MemoryStream();
var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt);
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();
var encrypted = msEncrypt.ToArray();
return (Convert.ToBase64String(encrypted));
}
The code below and in the Fiddle isn't for production, it is for educational purposes. I do not want to fix anything, as I have a viable solution. However, I would like to know why:
var password = "password";
var salt = Encoding.ASCII.GetBytes(password.Length.ToString());
var secret = new PasswordDeriveBytes(password, salt);
When the above is implemented, in the following method FixedEncryptor will work.
// Valid:
public static string FixedEncryptor(string content)
{
var cipher = new RijndaelManaged();
var plain = Encoding.Unicode.GetBytes(content);
var key = new PasswordDeriveBytes(password, salt);
using (var encrypt = cipher.CreateEncryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encrypt, CryptoStreamMode.Write))
{
crypto.Write(plain, 0, plain.Length);
crypto.FlushFinalBlock();
return Convert.ToBase64String(stream.ToArray());
}
}
However, if you implement:
var secret = new PasswordDeriveBytes("password",
Encoding.ASCII.GetBytes("password"));
The code will suddenly produce:
Run-time exception (line 70): Padding is invalid and cannot be
removed.
Stack Trace:
[System.Security.Cryptography.CryptographicException: Padding is
invalid and cannot be removed.] at Crypt.Decryptor(String content):
line 70 at Program.Main(): line 17
As denoted in the following method:
// Invalid:
public static string Encryptor(string content)
{
var cipher = new RijndaelManaged();
var plain = Encoding.Unicode.GetBytes(content);
var key = new PasswordDeriveBytes("password", Encoding.ASCII.GetBytes("password"));
using (var encrypt = cipher.CreateEncryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encrypt, CryptoStreamMode.Write))
{
crypto.Write(plain, 0, plain.Length);
crypto.FlushFinalBlock();
return Convert.ToBase64String(stream.ToArray());
}
}
So why can one successfully decrypt, while the other doesn't decrypt correctly and produces the above error?
A Fiddle with a small example is here.
From your posted code example your problem comes from the fact you are using two different salts.
In FixedEncryptor you use a salt of
Encoding.ASCII.GetBytes(password.Length.ToString());
That encodes to be a byte array equal to { 56 }, this is because Length returns 8 then calling ToString() on that returns the string "8" which you convert in to the ascii value 56.
In Encryptor you use a salt of
Encoding.ASCII.GetBytes("password")
That encodes to be a byte array equal to { 112, 97, 115, 115, 119, 111, 114, 100}, which is the ascii values of the characters "p", "a", "s", "s", "w", "o", "r", and "d".
The problem you are running in to is you only attempt to use { 56 } in your decrypt function, so your problem comes down to your encrypt function and your decrypt function are using two different salts.
If I make a make a new Decrypter to use the same salt and password as Encryptor then make a separate FixedDecryptor to match the salt of FixedEncryptor everything will work fine
public class Program
{
public static void Main()
{
var message = "Hello World!";
var fixedCipherText = Crypt.FixedEncryptor(message);
var cipherText = Crypt.Encryptor(message);
Console.WriteLine(cipherText);
Console.WriteLine(fixedCipherText);
var plainText = Crypt.Decryptor(cipherText);
var fixedPlainText = Crypt.FixedDecryptor(fixedCipherText);
Console.WriteLine(plainText);
Console.WriteLine(fixedPlainText);
}
}
public static class Crypt
{
private const string password = "password";
private readonly static byte[] salt = Encoding.ASCII.GetBytes(password.Length.ToString());
public static string FixedEncryptor(string content)
{
var cipher = new RijndaelManaged();
var plain = Encoding.Unicode.GetBytes(content);
var key = new PasswordDeriveBytes(password, salt);
using (var encrypt = cipher.CreateEncryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encrypt, CryptoStreamMode.Write))
{
crypto.Write(plain, 0, plain.Length);
crypto.FlushFinalBlock();
return Convert.ToBase64String(stream.ToArray());
}
}
public static string Encryptor(string content)
{
var cipher = new RijndaelManaged();
var plain = Encoding.Unicode.GetBytes(content);
var key = new PasswordDeriveBytes("password", Encoding.ASCII.GetBytes("password"));
using (var encrypt = cipher.CreateEncryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream())
using (var crypto = new CryptoStream(stream, encrypt, CryptoStreamMode.Write))
{
crypto.Write(plain, 0, plain.Length);
crypto.FlushFinalBlock();
return Convert.ToBase64String(stream.ToArray());
}
}
public static string FixedDecryptor(string content)
{
var cipher = new RijndaelManaged();
var encrypted = Convert.FromBase64String(content);
var key = new PasswordDeriveBytes(password, salt);
using (var decryptor = cipher.CreateDecryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream(encrypted))
using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
{
byte[] plain = new byte[encrypted.Length];
int decrypted = crypto.Read(plain, 0, plain.Length);
string data = Encoding.Unicode.GetString(plain, 0, decrypted);
return data;
}
}
public static string Decryptor(string content)
{
var cipher = new RijndaelManaged();
var encrypted = Convert.FromBase64String(content);
var key = new PasswordDeriveBytes("password", Encoding.ASCII.GetBytes("password"));
using (var decryptor = cipher.CreateDecryptor(key.GetBytes(32), key.GetBytes(16)))
using (var stream = new MemoryStream(encrypted))
using (var crypto = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
{
byte[] plain = new byte[encrypted.Length];
int decrypted = crypto.Read(plain, 0, plain.Length);
string data = Encoding.Unicode.GetString(plain, 0, decrypted);
return data;
}
}
}
Fiddel of the code.
However this still is not the "correct" way to do things. See Sine Nomen's answer
First of all, the method by which you generate a salt is not secure at all; secondly, PasswordDerivedBytes is deprecated and you should be looking at its successor, Rfc2898DeriveBytes.
Try something like the following - note that this requires a few using statements: System, System.IO, System.Security.Cryptography and System.Text.
Simply encrypt the data with Encrypt(PlainText, Password) and decrypt it again with Decrypt(EncryptedData, Password). The salt is rolled into the encrypted data as the first 16 bytes and it is completely random for each encryption/decryption round.
This code is part of my own open source password manager.
/*
* Encryption/Decryption, based on AES256 and PBKDF2
*/
public string Encrypt (string plainText, string passPhrase, bool fast_encrypt = false)
{
string result;
using (Rijndael algR = Rijndael.Create ()) {
RNGCryptoServiceProvider rngC = new RNGCryptoServiceProvider ();
byte[] iv = new byte[16];
rngC.GetBytes (iv);
Rfc2898DeriveBytes derived = new Rfc2898DeriveBytes (passPhrase, iv, fast_encrypt ? 10 : 3000);
algR.KeySize = 256;
algR.BlockSize = 128;
algR.Key = derived.GetBytes (32);
algR.IV = iv;
using (MemoryStream memoryStream = new MemoryStream ()) {
memoryStream.Write (iv, 0, 16);
using (CryptoStream cryptoStreamEncrypt = new CryptoStream (memoryStream, algR.CreateEncryptor (algR.Key, algR.IV), CryptoStreamMode.Write)) {
using (StreamWriter streamWriterEncrypt = new StreamWriter (cryptoStreamEncrypt)) {
streamWriterEncrypt.Write (plainText);
}
}
result = Convert.ToBase64String (memoryStream.ToArray ());
}
}
return result;
}
public string Decrypt (string cipherText, string passPhrase, bool fast_decrypt = false)
{
string result;
using (Rijndael algR = Rijndael.Create ()) {
using (MemoryStream memoryStream = new MemoryStream (Convert.FromBase64String (cipherText))) {
byte[] iv = new byte[16];
memoryStream.Read (iv, 0, 16);
Rfc2898DeriveBytes derived = new Rfc2898DeriveBytes (passPhrase, iv, fast_decrypt ? 10 : 3000);
algR.KeySize = 256;
algR.BlockSize = 128;
algR.Key = derived.GetBytes (32);
algR.IV = iv;
using (CryptoStream cryptoStreamDecrypt = new CryptoStream (memoryStream, algR.CreateDecryptor (algR.Key, algR.IV), CryptoStreamMode.Read)) {
using (StreamReader streamReaderDecrypt = new StreamReader (cryptoStreamDecrypt)) {
result = streamReaderDecrypt.ReadToEnd ();
}
}
}
}
return result;
}
I use RJ256 to login, since the return string is fairly small, it works (PHP gives encrypted string and C# needs to decrypt).
The data gets decrypted and fully works. Although, now I am transferring a 79KB string from PHP (Encrypted) to C# (Needs to Decrypt) and I get this error:
http://i.imgur.com/M4sgEct.png
This error only happens when the string is a bit larger than normally.
Here is my PHP code to encrypt:
private function _encrypt($data)
{
$iv = "sfhfskfsusfdsfd79fd8s79sdf789f79";
$key = "da4b9237bacccdf1";
// 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($data) % $block);
$data .= str_repeat(chr($padding), $padding);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv);
// this is not needed here
//$crypttext = urlencode($crypttext);
return base64_encode($crypttext);
}
Here is my C# Code to decrypt:
public static dynamic DecryptRJ256(string cypher, bool isJson = true, bool getBytes = false)
{
string sRet;
var encoding = new UTF8Encoding();
var key = encoding.GetBytes("da4b9237bacccdf1");
var iv = encoding.GetBytes("sfhfskfsusfdsfd79fd8s79sdf789f79");
using (var rj = new RijndaelManaged())
{
try
{
rj.Padding = PaddingMode.PKCS7;
rj.Mode = CipherMode.CBC;
rj.KeySize = 256;
rj.BlockSize = 256;
rj.Key = key;
rj.IV = iv;
var ms = new MemoryStream(Decode(cypher));
using (var cs = new CryptoStream(ms, rj.CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
sRet = sr.ReadLine();
}
}
}
finally
{
rj.Clear();
}
}
// ReSharper disable once AssignNullToNotNullAttribute
return (isJson ? JsonConvert.DeserializeObject<dynamic>(sRet) : (getBytes ? Encoding.UTF8.GetBytes(sRet) : (dynamic)sRet));
}
How can I make it work?
How about this:
public static byte[] DecryptRJ256(string prm_key, string prm_iv, string prm_text_to_decrypt)
{
var sEncryptedString = prm_text_to_decrypt;
var myRijndael = new RijndaelManaged();
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.Mode = CipherMode.CBC;
myRijndael.KeySize = 256;
myRijndael.BlockSize = 256;
byte[] key;
byte[] IV;
key = Encoding.ASCII.GetBytes(prm_key);
IV = Encoding.ASCII.GetBytes(prm_iv);
var decryptor = myRijndael.CreateDecryptor(key, IV);
var sEncrypted = Convert.FromBase64String(sEncryptedString);
var fromEncrypt = new byte[sEncrypted.Length];
var msDecrypt = new MemoryStream(sEncrypted);
var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Return (System.Text.Encoding.ASCII.GetString(fromEncrypt))
return fromEncrypt;
}