473,387 Members | 1,892 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

TripleDES String Encrypt/Decrypt Problem

I'm having trouble encrypting/decrypting a simple string using the
System.Security.Cryptography.TripleDESCryptoServic eProvider, etc...

The encryption works, but the decryption does not properly decrypt
several of the first few characters.

Here's the code:

class TMyCipher
{
public string Encipher(string s, string key)
{
byte[] bKey = ASCIIEncoding.ASCII.GetBytes(key);
TripleDESCryptoServiceProvider TripleDesProv = new
TripleDESCryptoServiceProvider();
ICryptoTransform ict = TripleDesProv.CreateEncryptor(bKey,null);
byte[] bInput = ASCIIEncoding.ASCII.GetBytes(s);
byte[] bOutput = ict.TransformFinalBlock(bInput,0,bInput.Length);
System.Console.WriteLine(System.Text.Encoding.ASCI I.GetString(bOutput,0,bOutput.Length));
return Convert.ToBase64String(bOutput,0,bOutput.Length);
}

public string Decipher(string ciphertext, string key)
{
byte[] bKey = ASCIIEncoding.ASCII.GetBytes(key);
TripleDESCryptoServiceProvider TripleDesDec = new
TripleDESCryptoServiceProvider();
ICryptoTransform Decryptor =
TripleDesDec.CreateDecryptor(bKey,null);
System.Console.WriteLine(ciphertext);
byte[] eInput = Convert.FromBase64String(ciphertext);
System.Console.WriteLine(System.Text.Encoding.ASCI I.GetString(eInput,0,eInput.Length));
byte[] eOutput =
Decryptor.TransformFinalBlock(eInput,0,eInput.Leng th);
return System.Text.Encoding.ASCII.GetString(eOutput,0,eOu tput.Length);
}
}

string ClearText = "test-text-this-is-text";

string sKey = "mykey";
sKey = sKey.PadRight(16,' ');
byte[] bKey = ASCIIEncoding.ASCII.GetBytes(sKey);
TMyCipher ciph = new TMyCipher();
string ciphertext = ciph.Encipher(ClearText,sKey);
System.Console.WriteLine(ciphertext);
string sFinal = ciph.Decipher(ciphertext,sKey);
System.Console.WriteLine("Final: " + sFinal);

The result:

G)♠SK|YS
M♀H)←b ↨\
r2xpLw1HKQbTy/zZh9MKTYzIqZtiCRfc
r2xpLw1HKQbTy/zZh9MKTYzIqZtiCRfc
G)♠SK|YS
M♀H)←b ↨\
Final: I'|htT<#t-this-is-text
Nov 15 '05 #1
8 13516
<wk****@yahoo.com> wrote:
I'm having trouble encrypting/decrypting a simple string using the
System.Security.Cryptography.TripleDESCryptoServic eProvider, etc...

The encryption works, but the decryption does not properly decrypt
several of the first few characters.


<snip>

The problem is that you're giving it more in one block than you should.
Rather than using the transform directly, I suggest you use the
CryptoStream API. That way you don't need to worry about block sizes
etc.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in message news:<MP************************@msnews.microsoft. com>...

The problem is that you're giving it more in one block than you should.
Rather than using the transform directly, I suggest you use the
CryptoStream API. That way you don't need to worry about block sizes
etc.


Thank you. I've tried to implement a simple solution using a
CryptoStream, but the results are almost identical:

My ClearText String
d!U#CP↕?¶XgN☼q%♀U∟o→
ZCHVo3eIQ1AShz+UWOdOj3GlDNUcbxoN <-- After Base64 Encoding.

d!U#CP↕?¶XgN☼q%♀U∟o→
My CleSRText String <-- After Decryption.
^^^^

Here's my code. Thanks again.

static void Main(string[] args)
{
string sKey = "MyKey";
sKey = sKey.PadRight(16,' ');
string sInit = "123456";
byte[] bInit = ASCIIEncoding.ASCII.GetBytes(sInit);
string ClearText = "My ClearText String";
byte[] bKey = ASCIIEncoding.ASCII.GetBytes(sKey);
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(ClearText);
byte[] rbuffer;

System.Console.WriteLine(ClearText);
TripleDESCryptoServiceProvider tdc = new
TripleDESCryptoServiceProvider();
ICryptoTransform icp = tdc.CreateEncryptor(bKey,bInit);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms,icp,CryptoStreamMode.Write);
cs.Write(buffer,0,buffer.Length);
cs.Close();
rbuffer = ms.ToArray();
System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(rbuffer,0,rbuffer.Length));
string CipherText =
Convert.ToBase64String(rbuffer,0,rbuffer.Length);
System.Console.WriteLine(CipherText);
System.Console.ReadLine();
ms.Close();

System.IO.MemoryStream dms = new System.IO.MemoryStream();
byte[] eBuffer = Convert.FromBase64String(CipherText);
System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(eBuffer,0,eBuffer.Length));
dms.Write(eBuffer,0,eBuffer.Length);
dms.Seek(0,System.IO.SeekOrigin.Begin);

TripleDESCryptoServiceProvider ddc = new
TripleDESCryptoServiceProvider();
ICryptoTransform dcp = ddc.CreateDecryptor(bKey,bInit);
CryptoStream dcs = new CryptoStream(dms,dcp,CryptoStreamMode.Read);
byte[] cBuffer = new byte[eBuffer.Length];
dcs.Read(cBuffer,0,eBuffer.Length);
dcs.Close();
System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(cBuffer,0,cBuffer.Length));
dms.Close();
string cText = ASCIIEncoding.ASCII.GetString(cBuffer,0,cBuffer.Le ngth);
System.Console.WriteLine(cText);
System.Console.ReadLine();
}
Nov 15 '05 #3
You need to use CryptoStream.FlushFinalBlock before closing the crypto
stream after writing.

<wk****@yahoo.com> wrote in message
news:2e**************************@posting.google.c om...
Jon Skeet [C# MVP] <sk***@pobox.com> wrote in message news:<MP************************@msnews.microsoft. com>...

The problem is that you're giving it more in one block than you should.
Rather than using the transform directly, I suggest you use the
CryptoStream API. That way you don't need to worry about block sizes
etc.


Thank you. I've tried to implement a simple solution using a
CryptoStream, but the results are almost identical:

My ClearText String
d!U#CP↕?¶XgN☼q%♀U∟o→
ZCHVo3eIQ1AShz+UWOdOj3GlDNUcbxoN <-- After Base64 Encoding.

d!U#CP↕?¶XgN☼q%♀U∟o→
My CleSRText String <-- After Decryption.
^^^^

Here's my code. Thanks again.

static void Main(string[] args)
{
string sKey = "MyKey";
sKey = sKey.PadRight(16,' ');
string sInit = "123456";
byte[] bInit = ASCIIEncoding.ASCII.GetBytes(sInit);
string ClearText = "My ClearText String";
byte[] bKey = ASCIIEncoding.ASCII.GetBytes(sKey);
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(ClearText);
byte[] rbuffer;

System.Console.WriteLine(ClearText);
TripleDESCryptoServiceProvider tdc = new
TripleDESCryptoServiceProvider();
ICryptoTransform icp = tdc.CreateEncryptor(bKey,bInit);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms,icp,CryptoStreamMode.Write);
cs.Write(buffer,0,buffer.Length);
cs.Close();
rbuffer = ms.ToArray();

System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(rbuffer,0,rbuffer.Len
gth)); string CipherText =
Convert.ToBase64String(rbuffer,0,rbuffer.Length);
System.Console.WriteLine(CipherText);
System.Console.ReadLine();
ms.Close();

System.IO.MemoryStream dms = new System.IO.MemoryStream();
byte[] eBuffer = Convert.FromBase64String(CipherText);
System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(eBuffer,0,eBuffer.Len
gth)); dms.Write(eBuffer,0,eBuffer.Length);
dms.Seek(0,System.IO.SeekOrigin.Begin);

TripleDESCryptoServiceProvider ddc = new
TripleDESCryptoServiceProvider();
ICryptoTransform dcp = ddc.CreateDecryptor(bKey,bInit);
CryptoStream dcs = new CryptoStream(dms,dcp,CryptoStreamMode.Read);
byte[] cBuffer = new byte[eBuffer.Length];
dcs.Read(cBuffer,0,eBuffer.Length);
dcs.Close();
System.Console.WriteLine(ASCIIEncoding.ASCII.GetSt ring(cBuffer,0,cBuffer.Len
gth)); dms.Close();
string cText = ASCIIEncoding.ASCII.GetString(cBuffer,0,cBuffer.Le ngth);
System.Console.WriteLine(cText);
System.Console.ReadLine();
}

Nov 15 '05 #4
<wk****@yahoo.com> wrote:
Thank you. I've tried to implement a simple solution using a
CryptoStream, but the results are almost identical:


Well, one of the problems which may well be everything in fact is that
you're using Stream.Read and assuming that it will completely fill the
buffer you've specified. You're also assuming that the encrypted length
is the same as the unencrypted length.

Rather than using CryptoStreamMode.Read, I find it easier to use
CryptoStreamMode.Write again, and write into a memory stream.

Here's some working code I wrote for someone else the other day - it
uses a straight DESCryptoServiceProvider, but I'm sure you can change
that part.

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

public class Working
{
DESCryptoServiceProvider provider;

Working()
{
provider = new DESCryptoServiceProvider();
provider.GenerateKey();
provider.GenerateIV();
}

byte[] Encrypt (string text)
{
byte[] encodedText = Encoding.UTF8.GetBytes (text);
ICryptoTransform transform = provider.CreateEncryptor();

using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream
(ms, transform, CryptoStreamMode.Write))
{
cs.Write (encodedText, 0, encodedText.Length);
cs.FlushFinalBlock();
}

return ms.ToArray();
}
}

string Decrypt (byte[] data)
{
ICryptoTransform transform = provider.CreateDecryptor();
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream (ms,
transform, CryptoStreamMode.Write))
{
cs.Write (data, 0, data.Length);
cs.FlushFinalBlock();
}
return Encoding.UTF8.GetString (ms.ToArray());
}
}

static void Main()
{
Working w = new Working();

Console.WriteLine (w.Decrypt(w.Encrypt
("Some text to be encrypted and then decrypted")));
}
}
--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #5
Bret Mulvey <br***@online.microsoft.com> wrote:
You need to use CryptoStream.FlushFinalBlock before closing the crypto
stream after writing.


Actually, if you close a CryptoStream without flushing the final block,
it'll flush it for you. Not a bad idea to make it clear though.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #6

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Bret Mulvey <br***@online.microsoft.com> wrote:
You need to use CryptoStream.FlushFinalBlock before closing the crypto
stream after writing.


Actually, if you close a CryptoStream without flushing the final block,
it'll flush it for you. Not a bad idea to make it clear though.


That's what I thought, but I tried his example and reproduced problem. Using
Close without FlushFinalBlock corrupted the data, and with FlushFinalBlock
before Close it resolved the problem. I was able to see this in his code as
well as a separate example I created.

In a decompilation of CryptoStream.Close I can clearly see where it calls
FlushFinalBlock, but only conditionally. Perhaps the TripleDES encryptor
doesn't correctly set this flag.
Nov 15 '05 #7

"Bret Mulvey" <br***@online.microsoft.com> wrote in message
news:3f********@news.microsoft.com...

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Bret Mulvey <br***@online.microsoft.com> wrote:
You need to use CryptoStream.FlushFinalBlock before closing the crypto
stream after writing.
Actually, if you close a CryptoStream without flushing the final block,
it'll flush it for you. Not a bad idea to make it clear though.


That's what I thought, but I tried his example and reproduced problem.

Using Close without FlushFinalBlock corrupted the data, and with FlushFinalBlock
before Close it resolved the problem. I was able to see this in his code as well as a separate example I created.

In a decompilation of CryptoStream.Close I can clearly see where it calls
FlushFinalBlock, but only conditionally. Perhaps the TripleDES encryptor
doesn't correctly set this flag.


Never mind, I can't back this up. I just re-ran my test that illustrated
this and it's not behaving the same so I must have made some other change.
It does look like the problem is on the reading side.
Nov 15 '05 #8
your problem is that you do not provide "good" IV in

TripleDesProv.CreateEncryptor(bKey, null);

if you put the same array for encr and decr, it works fine:
private byte[] bIV;
...
bIV = str2bytes("tXesterX");

// and use

ict = tProvider.CreateEncryptor(bKey, bIV);

// and

ict = tProvider.CreateDecryptor(bKey, bIV);

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 16 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Jonas | last post by:
I have the following perl program witch i use to encrypt a password file with. In perl 5.6 this program works like a charm but when trying it on the RED HAT EL 3 platform (taroon) is doesnt...
7
by: c duden | last post by:
I am attempting to encrypt some text and be able to decrypt it at a later time. I have two methods to do this: public static Byte EncryptText(string textToEncrypt, string encryptionHash) {...
7
by: Dica | last post by:
i've used the sample code from msdn to create an encyption/decryption assembly as found here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT10.asp i'm...
5
by: jdn | last post by:
I'm new to using this part of the framework, so I'm hoping I've done something obviously stupid, which someone will be able to point out in an obvious manner. Most of the samples I've seen...
2
by: GRB | last post by:
A client wants me to decrypt a cookie. They encrypted the data in java using TripleDES. The key provided is a 168 bit 44 character key, DESede alogorithm. Ive tried to decrypt in vb.net and get the...
1
by: d4v3y0rk | last post by:
i have a class i found/wrote (meaning i found it originally and tinkered with it to make it mine) and i would like some suggestions on how to make it better. i am looking for things i need to add,...
0
by: intersoln | last post by:
Hi, I tried encrypting and decrypting a string using the following Java code and key. And was successful. Then, I used the following C# to encrypt and decrypt a string using the following C#...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.