all groups > dotnet security > september 2005 >
You're in the

dotnet security

group:

TripleDESCryptoServiceProvider



TripleDESCryptoServiceProvider Tim Wallace
9/21/2005 12:17:53 PM
dotnet security: I'm experiencing something that I am not certain is normal or a problem. I
have a byte array that, once run through a method that encrypts using Triple
DES, the array now "appears" to be truncated. By this I mean that the final
three bytes are now showing 0 (zero) in the debugger. When I decrypt, the
string is now missing characters.

I encrypt like this (no, that is not the actual method name. yes, I have
this hardcoded for testing only and have omitted the key and iv array values
in this sample) :

public int Encrypt(ref MemoryStream a, ref MemoryStream b)
{
// the memory streams have a byte[] as the backing source
byte[] k = { };
byte[] i = { };
byte[] encBuffer = new byte[a.Length];
int iRead = 0, iTally = 0;

TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
tdes.Key = k;
tdes.IV = i;
CryptoStream encStream = new CryptoStream(b, tdes.CreateEncryptor(),
CryptoStreamMode.Write);

while ((iRead = a.Read(encBuffer, 0, encBuffer.Length)) > 0)
{
iTally += iRead;
encStream.Write(encBuffer, 0, iTally);
}

return iTally;
}

I decrypt like so:

public int Decrypt(ref MemoryStream a, ref MemoryStream b)
{
byte[] k = { };
byte[] i = { };
byte[] encBuffer = new byte[a.Length + 10];
int iRead = 0, iTally = 0;

try
{
TripleDESCryptoServiceProvider tdes = new
TripleDESCryptoServiceProvider();
CryptoStream decStream = new CryptoStream(b,
tdes.CreateDecryptor(k, i), CryptoStreamMode.Write);

while ((iRead = a.Read(encBuffer, iTally, (int)a.Length -
iRead)) > 0)
{
iTally += iRead;
decStream.Write(encBuffer, 0, iRead);
}

}
catch (Exception ex)
{
Console.WriteLine("ERROR...bytes read: {0}", iRead);
}

return iTally;
}

Any thoughts?

Re: TripleDESCryptoServiceProvider UPDATED Tim Wallace
9/22/2005 12:00:00 AM
I have been doing heavy debugging, as I must get this code working, and I've
found what I believe is a problem with the CryptoStream object. I'm
creating the MemoryStream with a byte[] backing containing 35 bytes. After
my encStream.Write call, the _position value (member of the underlying
MemoryStream class) is 32, not 35 as I would expect. When I look into the
CryptoStream object, I see that the _InputBufferSize member is 3, which is
the number of bytes "missing" when the loop ends. somehow, the final three
bytes are not being written in the Write call. Now, I have tried using
Flush(), but those three bytes don't get written. If I attempt to do a
FlushFinalBlock, I get an error: memory stream is not expandable.

None of this makes any sense (it should be working!), and I'm beating my
head against the wall over the situation. Any help would be greatly
appreciated.

Tim

[quoted text, click to view]

Re: TripleDESCryptoServiceProvider UPDATED Joe Kaplan (MVP - ADSI)
9/22/2005 12:32:23 PM
Have you read Ivan's sample code and discussion on symmetric encryption? He
has a pretty good "canonical" sample.

http://www.dotnetthis.com/Articles/Crypto.htm

Joe K.

[quoted text, click to view]

Re: TripleDESCryptoServiceProvider UPDATED Tim Wallace
9/22/2005 3:07:54 PM
Joe:

Thanks for the link. I changed my code to work exactly like Joe's sample,
but when the decrypting is completed, instead of the 35 bytes initially in
the byte array transmitted, I'm left with 24. Furthermore, when I try to
close the CryptoStream, I still get the "not expandable" error.

Any other ideas?

Tim

[quoted text, click to view]

Re: TripleDESCryptoServiceProvider UPDATED William Stacey [MVP]
9/22/2005 4:30:21 PM
I do it this way. Another neat thing is the same EncryptBytes and
DecryptBytes methods will work with 3Des and Rijndael unchanged. Just pass
the respective ICryptoTransform you need.

// Use the methods Sample:
TripleDESCryptoServiceProvider td = new
TripleDESCryptoServiceProvider();
// Set td key and iv here.
string clearString = "This string will be encrypted.";
byte[] clearData = Encoding.UTF8.GetBytes(clearString);
byte[] encData = Utils.EncryptBytes(td.CreateEncryptor(),
clearData);
clearData = Utils.DecryptBytes(td.CreateDecryptor(), encData);
clearString = Encoding.UTF8.GetString(clearData);
Console.WriteLine(clearString);

// Put these static methods in a Utils class or something.
public static byte[] EncryptBytes(ICryptoTransform encryptor, byte[] data)
{
if ( encryptor == null )
throw new ArgumentNullException("encryptor");
if ( data == null )
throw new ArgumentNullException("data");

using(MemoryStream msEncrypt = new MemoryStream())
using(CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
byte[] encrypted = msEncrypt.ToArray();
return encrypted;
}
}

public static byte[] DecryptBytes(ICryptoTransform decryptor, byte[]
encrypted)
{
if ( decryptor == null )
throw new ArgumentNullException("decryptor");
if ( encrypted == null )
throw new ArgumentNullException("encrypted");

using(MemoryStream msDecrypt = new MemoryStream(encrypted))
using(CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor,
CryptoStreamMode.Read))
{
byte[] fromEncrypt = new byte[encrypted.Length];
int read = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
if ( read < fromEncrypt.Length )
{
byte[] clearBytes = new byte[read];
Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0, read);
return clearBytes;
}
return fromEncrypt;
}
}

--
William Stacey [MVP]

[quoted text, click to view]

Re: TripleDESCryptoServiceProvider SOLVED Tim Wallace
9/23/2005 2:42:58 PM
William:

Thanks for your help. I ripped apart my implementation based upon Ivan's
sample, and discovered that I was using too large of a key. I made it 16
bytes and voila, it works.

Thanks for your follow-ups.

Tim

[quoted text, click to view]
AddThis Social Bookmark Button