TripleDESCryptoServiceProvider bad data error

J

JC

Hi all,

I have seem few messages posted regaring this but as yet have been
able to get this code to work. The plan was to encrypt some string
then pass the result to another function that woudl decrypt it -
please see below. Anyway i keep getting a 'bad data' exception. I'm
totally at a loss, so any help woudl be greatly appreciated.

public Byte[] myEncrypt()
{
UTF8Encoding utf8encoder = new UTF8Encoding();
Byte[] inputBytes = utf8encoder.GetBytes(txtToDb.Text);
//Console.WriteLine(inputBytes.ToString());

TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform =
tdesProvider.CreateEncryptor(tripleDes.Key,tripleDes.IV);

MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(encryptedStream,cryptoTransform,CryptoStreamMode.Write);

cryptStream.Write(inputBytes,0,inputBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;

Byte[] bResult = new Byte[encryptedStream.Length-1];
encryptedStream.Read(bResult,0,int.Parse(encryptedStream.Length.ToString())-1);
cryptStream.Close();
myDecrypt(bResult);
return bResult;
}


static string myDecrypt(Byte[] inputInBytes)
{
//UTF8Encoding utf8encoder = new UTF8Encoding();
TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();

ICryptoTransform cryptoTranform =
tdesProvider.CreateDecryptor(tripleDes.Key,tripleDes.IV);

MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(decryptedStream,cryptoTranform,CryptoStreamMode.Write);
cryptStream.Write(inputInBytes,0,inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position=0;

Byte[] result = new Byte[decryptedStream.Length-1];
decryptedStream.Read(result,0,int.Parse(decryptedStream.Length.ToString()));
cryptStream.Close();

UTF8Encoding myutf = new UTF8Encoding();
return myutf.GetString(result).ToString();
}
 
J

Jon Skeet [C# MVP]

JC said:
I have seem few messages posted regaring this but as yet have been
able to get this code to work. The plan was to encrypt some string
then pass the result to another function that woudl decrypt it -
please see below. Anyway i keep getting a 'bad data' exception. I'm
totally at a loss, so any help woudl be greatly appreciated.

Firstly, you're converting a MemoryStream to a byte array in a
roundabout way: the best way is to use MemoryStream.ToArray, which you
can even call after it's closed.

Secondly, there's no need to instantiate the UTF8Encoding - just use
Encoding.UTF8 which returns a singleton instance reference.

Having said that, I can't immediately see why it's likely to be
failing. Could you post a short but complete program which demonstrates
the problem?

See http://www.pobox.com/~skeet/csharp/complete.html for what I mean by
that.

I've looked at a few problems like this recently - I think it may be
time to write a page about it...
 
J

James Crane

Hi John,

Thanks for your reply. I have recreated a bare bones version to run and
show the error in a console app.

here's the code.

using System;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;

namespace demoEncrtptionForNewsGroup
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
myEncrypt();
}
public class tripleDes
{
public static byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
public static byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};

}
static void myEncrypt()
{
UTF8Encoding utf8encoder = new UTF8Encoding();
Byte[] inputBytes = utf8encoder.GetBytes("please encrypt me!");

TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform =
tdesProvider.CreateEncryptor(tripleDes.Key,tripleDes.IV);

MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(encryptedStream,cryptoTransform,CryptoStreamMode.Write);

cryptStream.Write(inputBytes,0,inputBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;

Byte[] bResult = new Byte[encryptedStream.Length-1];
encryptedStream.Read(bResult,0,int.Parse(encryptedStream.Length.ToStr
ing())-1);
cryptStream.Close();
myDecrypt(bResult);
}
static void myDecrypt(Byte[] inputInBytes)
{
TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();

ICryptoTransform cryptoTranform =
tdesProvider.CreateDecryptor(tripleDes.Key,tripleDes.IV);

MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(decryptedStream,cryptoTranform,CryptoStreamMode.Write);
cryptStream.Write(inputInBytes,0,inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position=0;

Byte[] result = new Byte[decryptedStream.Length-1];
decryptedStream.Read(result,0,int.Parse(decryptedStream.Length.ToStri
ng()));
cryptStream.Close();

UTF8Encoding myutf = new UTF8Encoding();
Console.WriteLine(myutf.GetString(result).ToString());
}
}
}

I hope this is what you were after, and thanks for you help.
 
J

Jon Skeet [C# MVP]

James Crane said:
Thanks for your reply. I have recreated a bare bones version to run and
show the error in a console app.

Right. The problem is really simple - sorry I didn't spot it before.

For some reason, you've decided to miss off the last byte of each of
the encrypted and decrypted data:
Byte[] bResult = new Byte[encryptedStream.Length-1];
encryptedStream.Read(bResult,0,int.Parse
(encryptedStream.Length.ToString())-1);

If you just use MemoryStream.ToArray instead, all is well.

I have to ask though - why were you converting the length into a string
and then parsing it? Why not just cast the long to an int?
 
J

James Crane

Hi Jon,

I have taken your advice and and now using MemoryStream.ToArray instead
and have removed the -1 and it works fine.

To be totally honest, the reason why I didnt cast the orinigal values is
because I'm still quite new to c# and wasnt thinking - I'll know for
next time.

Thanks for you help.

I've including the full working listing below for anyone else who needs
a reference.


using System;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;

namespace demoEncrtptionForNewsGroup
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
myEncrypt();
}
public class tripleDes
{
public static byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
public static byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};

}
static void myEncrypt()
{
UTF8Encoding utf8encoder = new UTF8Encoding();
Byte[] inputBytes = utf8encoder.GetBytes("please encrypt me!");

TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform =
tdesProvider.CreateEncryptor(tripleDes.Key,tripleDes.IV);

MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(encryptedStream,cryptoTransform,CryptoStreamMode.Write);

cryptStream.Write(inputBytes,0,inputBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;

Byte[] bResult = new Byte[encryptedStream.Length];
encryptedStream.Read(bResult,0,encryptedStream.ToArray().Length);
cryptStream.Close();
myDecrypt(bResult);
}
static void myDecrypt(Byte[] inputInBytes)
{
TripleDESCryptoServiceProvider tdesProvider = new
TripleDESCryptoServiceProvider();

ICryptoTransform cryptoTranform =
tdesProvider.CreateDecryptor(tripleDes.Key,tripleDes.IV);

MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new
CryptoStream(decryptedStream,cryptoTranform,CryptoStreamMode.Write);
cryptStream.Write(inputInBytes,0,inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position=0;

Byte[] result = new Byte[decryptedStream.Length];
decryptedStream.Read(result,0,decryptedStream.ToArray().Length);
cryptStream.Close();

UTF8Encoding myutf = new UTF8Encoding();
Console.WriteLine(myutf.GetString(result).ToString());
while(Console.Read()!='q');

}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top