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?
Tim Wallace - 22 Sep 2005 18:02 GMT
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
> 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
[quoted text clipped - 63 lines]
>
> Any thoughts?
Joe Kaplan (MVP - ADSI) - 22 Sep 2005 18:32 GMT
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.
>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
[quoted text clipped - 80 lines]
>>
>> Any thoughts?
Tim Wallace - 22 Sep 2005 20:07 GMT
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
> Have you read Ivan's sample code and discussion on symmetric encryption?
> He has a pretty good "canonical" sample.
[quoted text clipped - 88 lines]
>>>
>>> Any thoughts?
William Stacey [MVP] - 22 Sep 2005 21:30 GMT
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;
}
}

Signature
William Stacey [MVP]
> Joe:
>
[quoted text clipped - 99 lines]
>>>>
>>>> Any thoughts?
Tim Wallace - 23 Sep 2005 19:42 GMT
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
>I do it this way. Another neat thing is the same EncryptBytes and
>DecryptBytes methods will work with 3Des and Rijndael unchanged. Just pass
[quoted text clipped - 160 lines]
>>>>>
>>>>> Any thoughts?