2
I’m doing a college paper where I need to encrypt a string with AES and Md5.
When I do the encryption, returns the normal result (I think), but when I go decrypt, returns the following error:
Cryptographicexception: Input data is not a complete block
What could be this mistake?
Codes:
class Encryptor
{
//MD5
public static string GerarHashMd5(string input)
{
MD5 md5Hash = MD5.Create();
// Converter a String para array de bytes, que é como a biblioteca trabalha.
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
// Cria-se um StringBuilder para recompôr a string.
StringBuilder sBuilder = new StringBuilder();
// Loop para formatar cada byte como uma String em hexadecimal
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
//AES
static public byte[] encryptdata(byte[] bytearraytoencrypt, string key, string iv)
{
AesCryptoServiceProvider dataencrypt = new AesCryptoServiceProvider();
//Block size : Gets or sets the block size, in bits, of the cryptographic operation.
dataencrypt.BlockSize = 128;
//KeySize: Gets or sets the size, in bits, of the secret key
dataencrypt.KeySize = 128;
//Key: Gets or sets the symmetric key that is used for encryption and decryption.
dataencrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
//IV : Gets or sets the initialization vector (IV) for the symmetric algorithm
dataencrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
//Padding: Gets or sets the padding mode used in the symmetric algorithm
dataencrypt.Padding = PaddingMode.PKCS7;
//Mode: Gets or sets the mode for operation of the symmetric algorithm
dataencrypt.Mode = CipherMode.CBC;
//Creates a symmetric AES encryptor object using the current key and initialization vector (IV).
ICryptoTransform crypto1 = dataencrypt.CreateEncryptor(dataencrypt.Key, dataencrypt.IV);
//TransformFinalBlock is a special function for transforming the last block or a partial block in the stream.
//It returns a new array that contains the remaining transformed bytes. A new array is returned, because the amount of
//information returned at the end might be larger than a single block when padding is added.
byte[] encrypteddata = crypto1.TransformFinalBlock(bytearraytoencrypt, 0, bytearraytoencrypt.Length);
crypto1.Dispose();
//return the encrypted data
return encrypteddata;
}
//code to decrypt data
static public byte[] decryptdata(byte[] bytearraytodecrypt, string key, string iv)
{
AesCryptoServiceProvider keydecrypt = new AesCryptoServiceProvider();
keydecrypt.BlockSize = 128;
keydecrypt.KeySize = 128;
keydecrypt.Key = System.Text.Encoding.UTF8.GetBytes(key);
keydecrypt.IV = System.Text.Encoding.UTF8.GetBytes(iv);
keydecrypt.Padding = PaddingMode.PKCS7;
keydecrypt.Mode = CipherMode.CBC;
ICryptoTransform crypto1 = keydecrypt.CreateDecryptor(keydecrypt.Key, keydecrypt.IV);
byte[] returnbytearray = crypto1.TransformFinalBlock(bytearraytodecrypt, 0, bytearraytodecrypt.Length);
crypto1.Dispose();
return returnbytearray;
}
}
Encryption function:
private void criptografar_Click(object sender, EventArgs e)
{
string key;
string text;
string iv = "HR$2pIjHR$2pIj12"; // aleatório
string keyMd5;
key = Senha.Text;
keyMd5 = Encryptor.GerarHashMd5(key);
key = "";
text = Entrada.Text;
byte[] textArray = Encoding.UTF8.GetBytes(text); // conversão pra encryptar
byte[] encrypted = Encryptor.encryptdata(textArray, keyMd5, iv); // encryptador
Saida.Text = Encoding.UTF8.GetString(encrypted);
}
Decryption function:
private void descriptografar_Click(object sender, EventArgs e)
{
string key;
string text;
string iv = "HR$2pIjHR$2pIj12"; // aleatório
string keyMd5;
key = Senha.Text;
keyMd5 = Encryptor.GerarHashMd5(key);
key = "";
text = Entrada.Text;
byte[] textArray = Encoding.UTF8.GetBytes(text); // conversão pra encryptar
byte[] decrypted = Encryptor.decryptdata(textArray, keyMd5, iv); // decryptador
Saida.Text = Encoding.UTF8.GetString(decrypted);
}
And here is the result that generated the encryption: