I use AES to encrypt data in a web application. Everything works fine for me when the secret key does not contain any special characters. If I add any, the encryption works but not the decryption. I would like to know if the 16-character 128-bit secret key I am using allows the use of special characters or only alphanumeric characters instead. I can't figure it out with the Microsoft documentation. From what I read, the Key property is a value of type byte[] . If the length of the key in my case is 16 characters, it is an array of 16 bytes (128 bits). But I haven't found where they specify if those bytes have to be alphanumeric characters, special characters, etc.
The Ca function returns a string resulting from the encryption (E) or decryption (D) operation. Depending on the type of operation, the encryption or decryption function is used. Encryption never gives me any trouble, but decryption fails when I add a special character to the secret key. This secret key is a 16-character string set as the session value when the application loads.
The code is the following:
public string Ca(string texto, string operacion)
//Cifrado Aes (Ca)
{
string base64;
using (Aes myAes = Aes .Create())
{
myAes.Padding = PaddingMode.Zeros;
byte[] key_aes = Encoding.UTF8.GetBytes(Convert.ToString(HttpContext.Current.Session["key_AES"]));
if (key_aes == null || key_aes.Length == 0)
{
goto salida;
}
if (operacion == "E")
{
// Encrypt the string to an array of bytes.
byte[] encriptado = EncryptStringToBytes_Aes(texto, key_aes, key_aes);
//Convertimos en un string
base64 = Convert.ToBase64String(encriptado);
return base64;
}
else if (operacion == "D")
{
byte[] bytedesdeCampo = Encoding.UTF8.GetBytes(texto);
// Decrypt the bytes to a string.
try
{
string desencriptado = DecryptStringFromBytes_Aes(bytedesdeCampo, key_aes, key_aes);
return desencriptado;
}
catch (Exception e)
{ //este error se produce cuando la key no es correcta (EL relleno entre caracteres no es admitido y no se puede quitar)
string asdfads = e.Message;
if (e.Message.Contains("Longitud no válida"))
{
}
return texto;
}
}
salida:
return "";
}
}
static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
if (plainText.Length == 0)
{
return Encoding.UTF8.GetBytes("");
}
if (Key == null)
{
return Encoding.UTF8.GetBytes("");
}
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}
static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}