AES decrypt file data and write to disk - c#

I am trying to decrypt file data and write to disk. It's creating the file but it is corrupted. Could you please let me know if there are any suggestions. I am using AES 256 algorithm.
column_data = string_data //base64 encoded string
byte[] data_bytes = Convert.FromBase64String(column_data);
string decodedString = Encoding.UTF8.GetString(data_bytes);
bytes[] decrypted = DecryptAESText(decodedString, secret, iv);
File.WriteAllBytes(#".\file.gif", decrypted );
// DecryptAESText returns the decrypted text, receives text in Base64
public static byte[] DecryptAESText(string cipheredText, byte[] Key, byte[] IV)
{
IBufferedCipher cipher = InitAESCipher(false, Key, IV);
string plainText = string.Empty;
byte[] plainBytes = null;
try
{
byte[] cipheredBytes = Convert.FromBase64String(cipheredText);
plainBytes = new byte[cipher.GetOutputSize(cipheredBytes.Length)];
plainBytes = cipher.DoFinal(cipheredBytes);
}
catch (Exception e)
{
Console.WriteLine(e.ToString() + "Issue in DecryptAESText column Name:");
}
return plainBytes;
}

Related

PHP Token generation to C#.Net

I am tried to convert the php basic two way encryption code to C# code.the php code can be check with this site -> https://www.the-art-of-web.com/php/two-way-encryption/. I am not sure with the IV generate in my c# code is correct or not .The token which i have get from C# and PHP are in same format but the C# token shows invalid.please check my C# code that I need to change any thing.
PHP CODE:
<?php
$encrypted ="";
function encryptToken($token)
{
$cipher_method = 'aes-128-ctr';
$enc_key = openssl_digest('**********************', 'SHA256', TRUE);
$enc_iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));
$crypted_token = openssl_encrypt($token, $cipher_method, $enc_key, 0, $enc_iv) . "::" .
bin2hex($enc_iv);
unset($token, $cipher_method, $enc_key, $enc_iv);
return $crypted_token;
}
function createAccessToken(){
$now = date("YmdHis");
$secret = '###################';
$plainText = $now."::".$secret;
$encrypted = encryptToken($plainText);
return $encrypted;
}
$encrypted = createAccessToken();
?>
C# CODE
public string GenerateToken()
{
var Date = DateTime.Now.ToString("yyyyMMddHHmmss");
var secret = "#############################";
string plainText = Date + "::" + secret;
var accessToken = EncryptString(plainText);
return accessToken;
}
public string EncryptString(string plainText)
{
try
{
string password = "************************";
// Create sha256 hash
SHA256 mySHA256 = SHA256Managed.Create();
byte[] key = mySHA256.ComputeHash(Encoding.ASCII.GetBytes(password));
// Instantiate a new Aes object to perform string symmetric encryption
Aes encryptor = Aes.Create();
encryptor.Mode = CipherMode.ECB;
encryptor.Padding = PaddingMode.None;
encryptor.BlockSize = 128;
// Create secret IV
var iv = generateIV();
// Set key and IV
byte[] aesKey = new byte[32];
Array.Copy(key, 0, aesKey, 0, 32);
encryptor.Key = aesKey;
encryptor.IV = iv;
// Instantiate a new MemoryStream object to contain the encrypted bytes
MemoryStream memoryStream = new MemoryStream();
// Instantiate a new encryptor from our Aes object
ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();
// Instantiate a new CryptoStream object to process the data and write it to the
// memory stream
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);
// Convert the plainText string into a byte array
byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);
// Encrypt the input plaintext string
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
// Complete the encryption process
cryptoStream.FlushFinalBlock();
// Convert the encrypted data from a MemoryStream to a byte array
byte[] cipherBytes = memoryStream.ToArray();
// Close both the MemoryStream and the CryptoStream
memoryStream.Close();
cryptoStream.Close();
// Convert the encrypted byte array to a base64 encoded string
string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length) + "::" + ByteArrayToString(iv);
// Return the encrypted data as a string
return cipherText;
}
catch (Exception)
{
throw;
}
}
private static byte[] generateIV()
{
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] nonce = new byte[IV_LENGTH];
rng.GetBytes(nonce);
return nonce;
}
}
Received Tokens
PHP Token
s9kMVUTBLvvjDJNean2kYyEHisYsEQHLQ54+7wV1zHdV1jRsSBFc6PNU0lyZ48VoCjckpm94xEgxKpTRCCXEX8CS/7PYbxZqNBFIZBtZZ3mXnkfA4rvkVEc6XuNXqLGdU3dFxbtWhikAMkHiiUPnPP5hR9UCyj2mAzJqHAwQ1Cn5VkyYWwJEHeyzQR4cwBVr::2e7d77b69ab1185e3d44af142aa6f358
C# token
qFSf2qQ+UHcqAoGUxj43wTO9fLhxfhwf+hYiRKq12amdcICJ6swXvSlV4P1/VYQm6ezNqF+x6LkjMfsxgG1Oyo71+T+mtSs0j5Bmu7eaZr5bDgAMMnZ8WrDKde2fGOgB81Gkj67L/Ka+dT+Ki0j/zsXMN454vqCzdUl0pw91TpwB8UHYni7sMA8JyLgto3Q4::418c68da838e2be51b0e84def5266024

AES Encryption Windows Phone 8.1

I need to do 128 bit AES encryption on an application in Windows Phone 8.1. I used the following code for Encrypting and Decrypting the data respectively:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, null);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
But the encryption and decryption doesn't seem to be working properly. It is getting encrypted to some unicode characters and throwing a crash on decrypting:
Length is not a multiple of block size and no padding is
selected.\r\nParameter name: ciphertext
What am I doing wrong here? Can someone please help?
EDIT
After a lot more time with Google, I found the following methods for encryption and decryption, but they doesn't seem to work either.
public string GetEncryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string encrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(input));
encrypted = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(AES, Buffer, null));
return encrypted;
}
catch (Exception ex)
{
return null;
}
}
public string GetDecryptedContent(string input, string pass)
{
SymmetricKeyAlgorithmProvider SAP = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
CryptographicKey AES;
HashAlgorithmProvider HAP = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash Hash_AES = HAP.CreateHash();
string decrypted = "";
try
{
byte[] hash = new byte[32];
Hash_AES.Append(CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(pass)));
byte[] temp;
CryptographicBuffer.CopyToByteArray(Hash_AES.GetValueAndReset(), out temp);
Array.Copy(temp, 0, hash, 0, 16);
Array.Copy(temp, 0, hash, 15, 16);
AES = SAP.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
IBuffer Buffer = CryptographicBuffer.DecodeFromBase64String(input);
byte[] Decrypted;
CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(AES, Buffer, null), out Decrypted);
decrypted = Encoding.UTF8.GetString(Decrypted, 0, Decrypted.Length);
return decrypted;
}
catch (Exception ex)
{
return null;
}
}
EDIT 2
Finally managed to get the encryption working properly, but the decryption is still not working presumably because the encoding I am passing is not the right one:
private string GetEncryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[128 / 8]; // Adding this solved the encryption issue.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
private string GetDecryptedContent(string content)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(EncryptionKey);
byte[] data = Convert.FromBase64String(content); // Believe this is where the issue is, but not able to figure it out.
byte[] iv = new byte[128 / 8]; // Added this to make the decryption work the same way.
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
I finally solved the problem. The problem was with the text encoding. Using the correct encoding solved the issue. The working code below:
public static string EncryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Encoding.UTF8.GetBytes(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Encrypt(key, data, iv);
return Convert.ToBase64String(cipherText);
}
public static string DecryptAES(string content, string password)
{
byte[] keyMaterial = Encoding.UTF8.GetBytes(password);
byte[] data = Convert.FromBase64String(content);
byte[] iv = new byte[keyMaterial.Length];
var provider = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
byte[] cipherText = WinRTCrypto.CryptographicEngine.Decrypt(key, data, iv);
return Encoding.UTF8.GetString(cipherText, 0, cipherText.Length);
}
WinRTCrypto is available as part of PCLCrypto.

RSA decryption - Key does not exist

I'm trying to encrypt and decrypt file with RSA. Encryption is working fine. But I get error when I'm decrypting.
Error is key does not exist.
Here is the error: http://i.imgur.com/ebF09cU.png
public byte[] RSA_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes, RSAParameters RSAKeyInfo)
{
//initialze the byte arrays to the public key information.
byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
106,99,179,68,175,211,164,116,64,148,226,254,172,147};
//Values to store encrypted symmetric keys.
byte[] EncryptedSymmetricKey;
byte[] EncryptedSymmetricIV;
byte[] encryptedBytes = null;
// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(_stBitov))
{
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey;
//Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
var key = new Rfc2898DeriveBytes(PublicKey, saltBytes, 1000);
//Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
encryptedBytes = RSA.Encrypt(bytesToBeEncrypted, false);
}
}
return encryptedBytes;
}
RSAParameters _RSAKeyInfo;
public void EncryptFile()
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
//Get an instance of RSAParameters from ExportParameters function.
RSAParameters RSAKeyInfo = RSA.ExportParameters(false);
_RSAKeyInfo = RSAKeyInfo;
string path = ofd.FileName;
if (File.Exists(path))
{
string dirPath = Path.GetDirectoryName(path);
byte[] bytesToBeEncrypted = File.ReadAllBytes(path);
byte[] passwordBytes = File.ReadAllBytes(dirPath + "/KEY_" + ofd.SafeFileName);
byte[] bytesEncrypted = RSA_Encrypt(bytesToBeEncrypted, passwordBytes, RSAKeyInfo);
string fileEncrypted = dirPath + "/ENCRYPTED_" + ofd.SafeFileName;
File.WriteAllBytes(fileEncrypted, bytesEncrypted);
}
}
private void button5_Click(object sender, EventArgs e)
{
string path = ofd2.FileName;
if (File.Exists(path))
{
DecryptFile();
richTextBox4.Text = "Dekripcija uspesna";
}
else
{
richTextBox6.Text = "Datoteka ni dodana";
}
} private void richTextBox4_TextChanged(object sender, EventArgs e) { }
public byte[] RSA_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes, RSAParameters RSAKeyInfo)
{
byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
106,99,179,68,175,211,164,116,64,148,226,254,172,147};
//Values to store encrypted symmetric keys.
byte[] EncryptedSymmetricKey;
byte[] EncryptedSymmetricIV;
byte[] decryptedBytes = null;
// Set your salt here, change it to meet your flavor:
// The salt bytes must be at least 8 bytes.
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
using (MemoryStream ms = new MemoryStream())
{
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(_stBitov))
{
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = PublicKey;
//Import key parameters into RSA.
RSA.ImportParameters(RSAKeyInfo);
//Create a new instance of the RijndaelManaged class.
RijndaelManaged RM = new RijndaelManaged();
//Encrypt the symmetric key and IV.
EncryptedSymmetricKey = RSA.Encrypt(RM.Key, false);
EncryptedSymmetricIV = RSA.Encrypt(RM.IV, false);
decryptedBytes = RSA.Decrypt(bytesToBeDecrypted, false);
}
}
return decryptedBytes;
}
public void DecryptFile()
{
string path = ofd2.FileName;
if (File.Exists(path))
{
string dirPath = Path.GetDirectoryName(path);
byte[] bytesToBeDecrypted = File.ReadAllBytes(path);
byte[] passwordBytes = File.ReadAllBytes(dirPath + "/KEY_" + ofd.SafeFileName);
byte[] bytesDecrypted = RSA_Decrypt(bytesToBeDecrypted, passwordBytes, _RSAKeyInfo);
string file = dirPath + "/DECRYPTED_" + ofd.SafeFileName;
File.WriteAllBytes(file, bytesDecrypted);
}
}
Can somebody tell me what to do that decryption is going to work.
RSA is a kind of public-key cryptography. That means you need a public key to encrypt the message and a private key to decrypt your message. It looks like you're using your public key for both encryption and decryption. Where's your private key?
It seems you're trying to do hybrid encryption with RSA+AES, but you forgot to actually use AES to encrypt the plaintext and you forgot to encrypt the symmetric key with RSA. You also need to generate the symmetric key randomly and should not be derived from the public key which is supposed to be constant and public.
The error that you presented here is the least of your problems, but as ElectroByt already said, you need to use a private key (RSACryptoServiceProvider#ExportParameters(true)) to decrypt something with RSA. In your case, you would need to decrypt with RSA to get the symmetric key to use it to decrypt the symmetric ciphertext to get the actual message back.

AES Encryption using RijndaelManged Class: Baes64 encoding and decoding aes encryption string

So, I am having an issue with decrypting the decoded base64 aes string. Is this possible? I wrote a small console program to work this out but no luck. Here is my example:
As depicted, I have successfully converted the base64 back the aes encrypted string, but when I try to decrypt it I get more junk. If a code snippet is need let me. Thank you all for your help :)
UPDATE: Code snippet for decrypting method
static void Main(string[] args)
{
string plainText;
string decrypted;
string decryptedFromB64EncodedDecoded;
string fromBase64ToEncryptedText;
string encryptedText;
string encryptedTextBase64;
byte[] encryptedBytes;
byte[] encryptedBytes2;
byte[] encryptedBytesBase64;
RijndaelManaged crypto = new RijndaelManaged();
UTF8Encoding UTF = new UTF8Encoding();
Console.WriteLine("Please put in the text to be encrypted.");
plainText = Console.ReadLine();
try
{
encryptedBytes = encrypt(plainText, crypto.Key, crypto.IV);
encryptedText = Encoding.ASCII.GetString(encryptedBytes);
//encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);
encryptedTextBase64 = toBase64String(encryptedText);
encryptedBytesBase64 = fromBase64String(encryptedTextBase64);
fromBase64ToEncryptedText = Encoding.ASCII.GetString(encryptedBytesBase64);
encryptedBytes2 = Encoding.ASCII.GetBytes(fromBase64ToEncryptedText);
decrypted = decrypt(encryptedBytes, crypto.Key, crypto.IV);
decryptedFromB64EncodedDecoded = decrypt(encryptedBytes2, crypto.Key, crypto.IV);
Console.WriteLine("Start: {0}", plainText);
Console.WriteLine("Encrypted: {0}", encryptedText);
Console.WriteLine("Encrypted Base64: {0}", encryptedTextBase64);
Console.WriteLine("From Base64 To AES Encypted Text: {0}", fromBase64ToEncryptedText);
Console.WriteLine("Decrypted: {0}", decrypted);
Console.WriteLine("Decrypted From Encode and then Decode Base64 Text: {0}", decryptedFromB64EncodedDecoded);
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}
Console.ReadLine();
}
public static string decrypt (byte[] textToDecrypt, byte[] key, byte[] IV)
{
RijndaelManaged crypto = new RijndaelManaged();
MemoryStream stream = new MemoryStream(textToDecrypt) ;
ICryptoTransform decryptor = null;
CryptoStream cryptoStream = null;
StreamReader readStream = null;
string text = string.Empty;
try
{
crypto.Key = key;
crypto.IV = IV;
crypto.Padding = PaddingMode.None;
decryptor = crypto.CreateDecryptor(crypto.Key, crypto.IV);
cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);
//cryptoStream.Read(textToDecrypt, 0, textToDecrypt.Length);
readStream = new StreamReader(cryptoStream);
text = readStream.ReadToEnd();
cryptoStream.Close();
byte[] decodedValue = stream.ToArray();
return text;
}
catch (Exception)
{
throw;
}
finally
{
if (crypto != null)
{
crypto.Clear();
}
stream.Flush();
stream.Close();
}
}
public static byte[] encrypt(string text, byte[] key, byte[] IV)
{
RijndaelManaged crypto = null;
MemoryStream stream = null;
//ICryptoTransform is used to perform the actual decryption vs encryption, hash function are a version crypto transforms
ICryptoTransform encryptor = null;
//CryptoStream allows for encrption in memory
CryptoStream cryptoStream = null;
UTF8Encoding byteTransform = new UTF8Encoding();
byte[] bytes = byteTransform.GetBytes(text);
try
{
crypto = new RijndaelManaged();
crypto.Key = key;
crypto.IV = IV;
stream = new MemoryStream();
encryptor = crypto.CreateEncryptor(crypto.Key, crypto.IV);
cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
}
catch (Exception)
{
throw;
}
finally
{
if (crypto != null)
{
crypto.Clear();
}
cryptoStream.Close();
}
return stream.ToArray();
}
public static string toBase64String(string value)
{
UTF8Encoding UTF = new UTF8Encoding();
byte[] myarray = UTF.GetBytes(value);
return Convert.ToBase64String(myarray);
}
public static byte[] fromBase64String(string mystring)
{
//UTF8Encoding UTF = new UTF8Encoding();
//byte[] myarray = UTF.GetBytes(value);
return Convert.FromBase64String(mystring);
}
I don't know how you're decrypting but before you decrypt, you should convert the base 64 string to a byte array before sending it into the decryption.
byte[] encryptedStringAsBytes = Convert.FromBase64String(base64EncodedEncryptedValue);
Then with the byte array you can pass to the CryptoStream via a MemoryStream.
UPDATE
I believe the issue is how you're setting up your streams
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Padding = paddingMode;
rijndaelManaged.Key = key;
rijndaelManaged.IV = initVector;
MemoryStream memoryStream = null;
try
{
memoryStream = new MemoryStream(valueToDecrypt);
using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader(cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
finally
{
if (memoryStream != null)
memoryStream.Dispose();
}
}
UPDATE 2
This is how you should basically perform the steps.
To encrypt
Encode your plain text string using the Encoding.GetBytes(stringToEncrypt)
pass the byte[] into the crypto API (via memory stream, etc.)
get the bytes from the encrypted stream and encode the results as Base64
To Decrypt (do the reverse)
Convert the base64 encoded string to bytes using Convert.FromBase64String(base64EncodedEncryptedValue)
pass that byte array into your decryption function above
Try:
encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);
Based on your comment. The bytes are just that bytes, so in order to decrypt the ciphertext you need to undo any encoding or series of encodings you have done.
If you really want to go from Encrypted Bytes -> Base64String -> ASCII string -> then decrypt that ASCII string? you would need to base64 decode the ascii string then convert that string to bytes using
Encoding.ASCII.GetBytes(yourdecodedstring);
Note that base 64 decoding is not the same as using Convert.FromBase84String.

C# UTF8 Encoding issue with AES Encryption

I'm creating a TCP based chat client. I'm trying to Encrypt some of the data with AES (more security) I have a AES encryption class and it uses UTF-8 by default as the out going and incoming Encoding type. But for some reason when i pass the information over the TCPClient (using UTF-8) and get it the other side it is throwing an error:
`System.Security.Cryptography.CryptographicException: Length of the data to decrypt is invalid.
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()`
So I recreated the problem without using the TCP client, just taking the AES encrypted data and putting it through a UTF-8 Encoding system that gets the string of the byte array then re-gets the byte array all using UTF-8 (basically the same thing as what happens over the network (without the string))
This method works:
string dataToEncrypt = "Hello World";
byte[] key = Encryption.AesEncryption.GenerateKey(32);
byte[] iv = Encryption.AesEncryption.GenerateKey(16);
byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);
string decrypted = Encryption.AesEncryption.DecryptedBytes(encrypted, key, iv);
The method doesn't work (throws the error from above)
Encoding encoding = Encoding.UTF8;
string dataToEncrypt = "Hello World";
byte[] key = Encryption.AesEncryption.GenerateKey(32);
byte[] iv = Encryption.AesEncryption.GenerateKey(16);
byte[] encrypted = Encryption.AesEncryption.EncryptString(dataToEncrypt, key, iv);
string encstring = encoding.GetString(encrypted);
byte[] utf8encrypted = encoding.GetBytes(encstring);
string decrypted = Encryption.AesEncryption.DecryptedBytes(utf8encrypted, key, iv);
What am i doing wrong?
This is my Encryption Class:
public sealed class AesEncryption
{
private byte[] Key;
public Encoding Encoder = Encoding.UTF8;
public AesEncryption(byte[] key)
{
Key = key;
}
public byte[] Encrypt(string text, byte[] iv)
{
var bytes = Encoder.GetBytes(text);
var rm = new RijndaelManaged();
var encrypter = rm.CreateEncryptor(Key, iv);
var ms = new MemoryStream();
var cs = new CryptoStream(ms, encrypter, CryptoStreamMode.Write);
cs.Write(bytes, 0, bytes.Length);
cs.FlushFinalBlock();
var output = ms.ToArray();
cs.Close();
ms.Close();
return output;
}
public string Decrypt(byte[] encrypted, byte[] iv)
{
var ms = new MemoryStream();
var cs = new CryptoStream(ms,
new RijndaelManaged().CreateDecryptor(Key, iv),
CryptoStreamMode.Write);
cs.Write(encrypted, 0, encrypted.Length);
cs.FlushFinalBlock();
var output = ms.ToArray();
cs.Close();
ms.Close();
return Encoder.GetString(output);
}
public static byte[] EncryptString(string text, byte[] key, byte[] iv)
{
var ec = new AesEncryption(key);
return ec.Encrypt(text, iv);
}
public static string DecryptedBytes(byte[] encrypted, byte[] key, byte[] iv)
{
var ec = new AesEncryption(key);
return ec.Decrypt(encrypted, iv);
}
public static byte[] GenerateKey(int length)
{
Random rnd = new Random();
var chars = "1!2#3#4$5%6^7&8*9(0)-_=+qQwWeErRtTyYuUiIoOpP[{]}\\|aAsSdDfFgGhHjJkKlL;:'\"zZxXcCvVbBnNmM,<.>/?".ToCharArray();
string randomizedKey = "";
for (int i = 0; i < length; i++)
{
randomizedKey += chars[rnd.Next(0, chars.Length)];
}
return randomizedKey.ToByteArray();
}
}
UTF-8 does not perfectly represent the bytes. The short and simple answer is: Transmit bytes, not a UTF-8 string. If you must have a string, encode it in Base64.

Categories

Resources