ChronosMOT
ChronosMOT

Reputation: 341

Decryption with CryptoStream using aes fails

I'm writing two applications one encrypts files the other has to read. While the encryption and decryption in the first program works the second is not able to decrypt the file.

This is the code that encrypts the data:

using (Aes aes = getAes())
{
    ICryptoTransform aesEncrypt = aes.CreateEncryptor();
    doCrypt(filePath, aesEncrypt);
}

with doCrypt:

private void doCrypt(string filePath, ICryptoTransform aesCrypto)
{
    doCrypt(filePath, filePath, aesCrypto);
}
private void doCrypt(string sourceFilePath, string targetFilePath, ICryptoTransform aesCrypto)
{
    byte[] input = File.ReadAllBytes(sourceFilePath);
    FileStream cryptoFS = new FileStream(targetFilePath, FileMode.Create);
    CryptoStream cryptoStream = new CryptoStream(cryptoFS, aesCrypto, CryptoStreamMode.Write);
    cryptoStream.Write(input, 0, input.Length);

    cryptoStream.Close();
    cryptoFS.Close();
}

and getAes:

public Aes getAes()
{
    Aes aes = AesCryptoServiceProvider.Create();
    MD5 keyHasher = MD5.Create();

    aes.Mode = CipherMode.ECB;
    aes.KeySize = 128;
    aes.BlockSize = 128;
    aes.Padding = PaddingMode.Zeros;
    aes.Key = keyHasher.ComputeHash(System.Text.Encoding.ASCII.GetBytes(pswdTB.Text));

    return aes;
}

Note: IV is not set, because aes runs in ECB-Mode, which does not use an IV

And this is the code to decrypt in the second application:

Aes aes = getAes();
//MemoryStream ms = new MemoryStream();
//CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);

//cs.Write(data, 0, data.Length);
//cs.Close();
//result = ms.ToArray();
//ms.Close();

FileStream cryptoFS = new FileStream("test.txt", FileMode.Create);
CryptoStream cryptoStream = new CryptoStream(cryptoFS, aes.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(data, 0, data.Length);

cryptoStream.Close();
cryptoFS.Close();

aes.Dispose();

I need the result to be in the byte[] result, but for debugging purposes I replaced it with a file output.

Edit While I do get output, it's not decrypted properly. This is a short peace of the resulting test.txt: "ꕾ㩈ႂ⤙͊꼥聓綨炌磌腼ꀽ鞍壃" The file was an XML file before en- and decrypton.

The getAes here is a copy, the only difference is, that the key is supplied by another method. But I checked the keys used are equal.

Upvotes: 0

Views: 2265

Answers (1)

xanatos
xanatos

Reputation: 111810

In .NET the CryptoStream has two "modes".

To encrypt you build it like:

CryptoStream cryptoStream = new CryptoStream(outputEncryptedStream, aesCrypto, CryptoStreamMode.Write);

to decrypt you build it like:

CryptoStream cryptoStream = new CryptoStream(inputEncryptedStream, aesCrypto, CryptoStreamMode.Read);

In both cases you must pass the encrypted/would be encrypted stream as the first parameter.

To encrypt something you can:

input.CopyTo(cryptoStream);
cryptoStream.FlushFinalBlock();

To decrypt something you can

cryptoStream.CopyTo(output);

(you don't need/can't use FlushFinalBlock to decrypt)

where input and output are the non-encrypted streams.

Upvotes: 2

Related Questions