Reputation: 61
I'm trying to encrypt image files using Rijndael encryption and I must be doing something wrong because the decrypted files are coming out with extra data at the front of the file any maybe a little extra at the end. I'm fairly new to this encryption algorithm so I'm pretty sure I'm just missing something simple.
Examples using text files
Input file
"the quick brown fox jumped over the lazy yellow dog"
Output file when I try to put a generated IV at the front of the file(\0=null)
"ÚñjÐæƒÊW®ï¡_Ü&ßthe\0 quick brown fox jumped over the lazy yellow dog"
Output file when I try to put an IV that is equal to my Key at front
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0the\0\0\0\0\0\0 quick brown fox jumped over the lazy yellow dog"
Output file when I use an IV that is equal to my Key and put nothing at front of file
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0the\0\0\0\0\0\0 quick brown fox jumped over the lazy yellow dog"
CODE
private RijndaelManaged GetCipher(byte[] key, bool forEncrypt)
{
RijndaelManaged rijndaelCipher;
rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
rijndaelCipher.Key = key;
/* if (forEncrypt)
rijndaelCipher.GenerateIV();
else
rijndaelCipher.IV = new byte[16];*/
rijndaelCipher.IV = _imageKey;
return rijndaelCipher;
}
public void DecryptStamp(Stamp stampToDecrypt, string decrpytedStampFilePath)
{
RijndaelManaged rijndaelCipher;
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block;
int numberRead;
ICryptoTransform transform;
if (!File.Exists(stampToDecrypt.Path))
throw new FileNotFoundException(stampToDecrypt.Path + " does not exist");
rijndaelCipher = this.GetCipher(_imageKey, false);
block = new byte[16];
try
{
inputStream = File.Open(stampToDecrypt.Path, FileMode.Open, FileAccess.Read);
outputStream = File.Open(decrpytedStampFilePath, FileMode.Create, FileAccess.Write);
//inputStream.Read(rijndaelCipher.IV, 0, rijndaelCipher.IV.Length);
transform = rijndaelCipher.CreateDecryptor();
encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
while ((numberRead = inputStream.Read(block, 0, block.Length)) > 0)
{
Console.WriteLine(numberRead.ToString());
encryptSteam.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
}
public Stamp EncryptStampToStampFolder(string stampFileToEncrpyt)
{
Configuration config;
Stamp stampToEncrypt;
RijndaelManaged rijndaelCipher;
string encryptedFilePath;
if (!File.Exists(stampFileToEncrpyt))
throw new FileNotFoundException(stampFileToEncrpyt + " does not exist");
config = Configuration.GetProgramInstance();
encryptedFilePath = Path.Combine(config.StampFolder, Path.GetFileNameWithoutExtension(stampFileToEncrpyt) + ".stmp");
stampToEncrypt = new Stamp(Path.GetFileNameWithoutExtension(stampFileToEncrpyt), encryptedFilePath);
rijndaelCipher = this.GetCipher(_imageKey, true);
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block = new byte[16];
int numberRead;
try
{
inputStream = File.Open(stampFileToEncrpyt, FileMode.Open, FileAccess.Read);
outputStream = File.Open(encryptedFilePath, FileMode.Create, FileAccess.Write);
//outputStream.Write(rijndaelCipher.IV, 0, 16);
encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
encryptSteam.Write(block, 0, block.Length);
while ((numberRead = inputStream.Read(block, 0, block.Length)) > 0)
{
encryptSteam.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
return stampToEncrypt;
}
public struct Stamp
{
public string Name,
Path;
public Stamp(string StampName, string StampPath)
{
Name = StampName;
Path = StampPath;
}
}
CODE post fix
private RijndaelManaged GetCipher(byte[] key, bool forEncrypt)
{
RijndaelManaged rijndaelCipher;
rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
rijndaelCipher.Key = key;
if (forEncrypt)
rijndaelCipher.GenerateIV();
else
rijndaelCipher.IV = new byte[16];
//rijndaelCipher.IV = _imageKey;
return rijndaelCipher;
}
public void DecryptStamp(Stamp stampToDecrypt, string decrpytedStampFilePath)
{
RijndaelManaged rijndaelCipher;
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block;
int numberRead;
ICryptoTransform transform;
if (!File.Exists(stampToDecrypt.Path))
throw new FileNotFoundException(stampToDecrypt.Path + " does not exist");
rijndaelCipher = this.GetCipher(_imageKey, false);
block = new byte[16];
try
{
inputStream = File.Open(stampToDecrypt.Path, FileMode.Open, FileAccess.Read);
outputStream = File.Open(decrpytedStampFilePath, FileMode.Create, FileAccess.Write);
inputStream.Read(rijndaelCipher.IV, 0, rijndaelCipher.IV.Length);
transform = rijndaelCipher.CreateDecryptor();
encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
while ((numberRead = inputStream.Read(block, 0, block.Length)) > 0)
{
encryptSteam.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
}
public Stamp EncryptStampToStampFolder(string stampFileToEncrpyt)
{
Configuration config;
Stamp stampToEncrypt;
RijndaelManaged rijndaelCipher;
string encryptedFilePath;
if (!File.Exists(stampFileToEncrpyt))
throw new FileNotFoundException(stampFileToEncrpyt + " does not exist");
config = Configuration.GetProgramInstance();
encryptedFilePath = Path.Combine(config.StampFolder, Path.GetFileNameWithoutExtension(stampFileToEncrpyt) + ".stmp");
stampToEncrypt = new Stamp(Path.GetFileNameWithoutExtension(stampFileToEncrpyt), encryptedFilePath);
rijndaelCipher = this.GetCipher(_imageKey, true);
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block = new byte[16];
int numberRead;
try
{
inputStream = File.Open(stampFileToEncrpyt, FileMode.Open, FileAccess.Read);
outputStream = File.Open(encryptedFilePath, FileMode.Create, FileAccess.Write);
outputStream.Write(rijndaelCipher.IV, 0, 16);
encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
//encryptSteam.Write(block, 0, block.Length); this line was the problem in the orginal code
while ((numberRead = inputStream.Read(block, 0, block.Length)) > 0)
{
encryptSteam.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
return stampToEncrypt;
}
public struct Stamp
{
public string Name,
Path;
public Stamp(string StampName, string StampPath)
{
Name = StampName;
Path = StampPath;
}
}
New Code's output
"7p¶¼oò¾½G€¢9±hfox\0\0 jumped over the lazy yellow dog"
Upvotes: 4
Views: 1053
Reputation: 61
The problem was three fold. 1)Extra data being written during encryption 2)The IV at the beginning of the file was being overwritten 3)The IV was not being read properly on decryption
CODE Fixed
private RijndaelManaged GetCipher(byte[] key, bool forEncrypt)
{
RijndaelManaged rijndaelCipher;
rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 0x80;
rijndaelCipher.BlockSize = 0x80;
rijndaelCipher.Key = key;
if (forEncrypt)
rijndaelCipher.GenerateIV();
else
rijndaelCipher.IV = new byte[16];
//rijndaelCipher.IV = _imageKey;
return rijndaelCipher;
}
public void DecryptStamp(Stamp stampToDecrypt, string decrpytedStampFilePath)
{
RijndaelManaged rijndaelCipher;
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block;
int numberRead;
ICryptoTransform transform;
if (!File.Exists(stampToDecrypt.Path))
throw new FileNotFoundException(stampToDecrypt.Path + " does not exist");
rijndaelCipher = this.GetCipher(_imageKey, false);
block = new byte[16];
try
{
inputStream = File.Open(stampToDecrypt.Path, FileMode.Open, FileAccess.Read);
outputStream = File.Open(decrpytedStampFilePath, FileMode.Create, FileAccess.Write);
//This line was wrong because rijndaelCipher.IV never filled
//inputStream.Read(rijndaelCipher.IV, 0, rijndaelCipher.IV.Length);
inputStream.Read(block, 0, block.Length);
rijndaelCipher.IV = block;
block = new byte[16];
transform = rijndaelCipher.CreateDecryptor();
encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
while ((numberRead = inputStream.Read(block, 0, block.Length)) > 0)
{
encryptSteam.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
}
public Stamp EncryptStampToStampFolder(string stampFileToEncrpyt)
{
Configuration config;
Stamp stampToEncrypt;
RijndaelManaged rijndaelCipher;
string encryptedFilePath;
if (!File.Exists(stampFileToEncrpyt))
throw new FileNotFoundException(stampFileToEncrpyt + " does not exist");
config = Configuration.GetProgramInstance();
encryptedFilePath = Path.Combine(config.StampFolder, Path.GetFileNameWithoutExtension(stampFileToEncrpyt) + ".stmp");
stampToEncrypt = new Stamp(Path.GetFileNameWithoutExtension(stampFileToEncrpyt), encryptedFilePath);
rijndaelCipher = this.GetCipher(_imageKey, true);
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
FileStream inputStream = null;
FileStream outputStream = null;
CryptoStream encryptSteam = null;
byte[] block = new byte[16];
int numberRead;
try
{
inputStream = File.Open(stampFileToEncrpyt, FileMode.Open, FileAccess.Read);
outputStream = File.Open(encryptedFilePath, FileMode.Create, FileAccess.Write);
outputStream.Write(rijndaelCipher.IV, 0, IV.Length);
//This had to be changed so that the IV was not overwitten
//encryptSteam = new CryptoStream(outputStream, transform, CryptoStreamMode.Write);
encryptSteam = new CryptoStream(inputStream, transform, CryptoStreamMode.Read);
//this line was a problem in the orginal code that caused extra data to be added to the encrypted file
//encryptSteam.Write(block, 0, block.Length);
while ((numberRead = encryptSteam.Read(block, 0, block.Length)) > 0)
{
outputStream.Write(block, 0, numberRead);
}
}
finally
{
rijndaelCipher.Clear();
rijndaelCipher.Dispose();
if (encryptSteam != null)
encryptSteam.Dispose();
if (outputStream != null)
outputStream.Dispose();
if (inputStream != null)
inputStream.Dispose();
}
return stampToEncrypt;
}
public struct Stamp
{
public string Name,
Path;
public Stamp(string StampName, string StampPath)
{
Name = StampName;
Path = StampPath;
}
}
Upvotes: 2
Reputation: 49189
Here's what I do to decrypt:
private RijndaelManaged GetAesProvider(Stream stm, bool isEncryption)
{
byte[] finalKey = GetFinalKey();
// GetIV either gets salt on encryption and writes it into stm
// or reads it from stm if it's decryption
byte[] iv = GetIV(stm, isEncryption);
RijndaelManaged aes = new RijndaelManaged();
aes.BlockSize = kAesBlockSizeInBytes * 8;
aes.IV = iv;
aes.Key = finalKey;
aes.Mode = CipherMode.CBC;
return aes;
}
public override Stream GetDecryptionStream(Stream source)
{
if (source.Length <= kIVSize)
{
return new EmptyStream();
}
RijndaelManaged aes = GetAesProvider(source, false);
ICryptoTransform xform = aes.CreateDecryptor(aes.Key, aes.IV);
return new CryptoStream(source, xform, CryptoStreamMode.Read);
}
Upvotes: 0