Introduction

The Compact Framework omits the main encryption features in the Cryptography namespace to make room for more important features. Fortunately, it is not terribly difficult to implement some sort of cryptography to hide your sensitive data. I wanted to find a small algorithm that was secure and portable. After doing a little searching, I ran across the Tiny Encryption Algorithm (TEA). This algorithm was developed in 1994 by David Wheeler and Roger Needham of Cambridge University. This algorithm is extremely portable, and fast. There has been a successful cryptanalysis performed on the original TEA algorithm which caused the original authors to modify the TEA algorithm. The revised algorithm is called XTEA. There is not much information on this algorithm so there is no guarantee that the XTEA algorithm has not been broken as well. However, this algorithm could still be useful for applications that do not require the highest of security. The original algorithm was developed in C, but constructed in such a way that it is easy to port to other languages, like C#. I was able to port the original C algorithm to C# with minimal changes. I tested the algorithm on the full .NET Framework as well as the .NET Compact Framework and it works great on both platforms with no changes.For more information on how TEA encryption works, refer to the links at the bottom of this article.

Background

The Tiny Encryption Algorithm works on the principle of paired blocks of data. This makes it a little more challenging to prepare strings for encryption because you need to pass pairs of unsigned integers to the algorithm and then store them in some manner so the data can be recovered at a later point in time. I use some bit shifting to convert between integers and strings, so a little knowledge of number systems will help you out.

Using the code

Porting the code to C# was the easy part. After porting the C algorithm to C#, I ended up with the following function for encryption:

Note: I only modified what was necessary to get the code to compile. I also formatted the code to make it a little more readable. In the original algorithm, they used an unsigned long for the variables. In C, an unsigned is a 32-bit unsigned integer. In .NET land, the equivalent is an unsigned integer.

Now we have reached the challenging part. To use the algorithm with strings, we have to convert the strings into an acceptable format. Here is a basic run-through of what I did to make use of the algorithm:

Make the string an even length by adding a space to the end of it if necessary. We need to do this because the algorithm expects pairs of data.

Convert the string to an array of bytes.

Loop through the array and pass a pair of values to the encrypt function.

Convert the two cipher values to strings and append to one long string.

The ConvertUIntToString function takes advantage of some shifting and bitwise-anding (&) to convert a 32-bit unsigned integer to a string of length 4. Since a character is 1 byte in length, we can combine 4 characters to make 4 bytes or 32 bits. Gee, that would hold a 32-bit unsigned integer (uint) nicely! Wow!

The problem is that the (standard) ASCII Encoding works well for the english alphabet, but you'll have trouble with Umlauts as well as diacritics used in many other languages. You could specify codepage 850 (extended ASCII) which includes ÄÜÖ (see Ascii Table) like this:

Encoding extendedAscii = Encoding.GetEncoding(850);

Then you can call extendedAscii.GetByte(..) and extendedAscii.GetString(..) to get the desired result

hi all,,i have this problem.. i use the tea encryption with MS SQL DB.i store the encrypted msg in a field of a table, then store the key in another field..But when i retreive the encrypted msg with its key.. and try to (decrypt) it.. it changes into another encrypted string.. this probleb happens only with strings retreived from SQL DB.what should i do????!!!!!!!!! Rashad.S.Majali

hi all,,i have this problem.. i use the tea encryption with MS SQL DB.i store the encrypted msg in a field of a table, then store the key in another field..But when i retreive the encrypted msg with its key.. and try to (decrypt) it.. it changes into another encrypted string.. this probleb happens only with strings retreived from SQL DB.what should i do????!!!!!!!!!

Note that the algorthm still "works" with this flaw, it is simply inefficient. Since only one byte is passed in per dword, you end up needing to perform 4x as many passes, and the resulting cryptext is 4x as long as it needs to be.

I went through all of the trouble of implementing this only to find that my decryption didn't work because someone else had done encryption correctly in C++... With your tip, finding and fixing the problem was much easier. Thank you!!!

The first suggestion would be to stick to the basic element of computation which is the byte to make it more effective.

Second suggestion is that once you had your byte encoder/decoder you can wrap them with another method that would convert the string to a byte array. Look at the System.Text.Encoding.UTF8.GetBytes method. You want UTF8 rather than ASCII to preserve foreign characters.

3rd suggestion is doing more checking -yes, even for an example you are what you publish- one of your method gets a string parameters and immediately goes about throwing an exception if the string length is incorrect BUT it forgets to first check if that string parameter is null. A null parameter would make the code crap out with a NullPointer exception

4th suggestion. You want a plain text passphrase but it can be feed a string that is null or too short or too long. The TEA key size is 128 bits. Your easiest way without having to pad a passphrase is to simply take that passphrase, use GetBytes (see above) to get a byte array and feed it to an MD5CryptoServiceProvider instance to generate a 128-bit hash which you can use as key. That hash will always be 128 bits regardless of your passphrase length.

i tried implementing this application in a far more complex application for encrypting and decrypting data... unfortunatelly, a problem occures every time i try decryptiong data from a file (btw, the file contains encrypted data -- obviously, with the same algorithm).there would be one more thing to say... this only occures to specific keys (e.g.: "cheietest1002345")

the problem consists in an ArgumentOutOfRangeException in one of this lines:

After some poking around i noticed it was due to some line end escape sequences that happend to be the result of the conversion with some data. Use the StreamReader.Read instead of ReadLine , and convert the chars to a string after you are done.

I am trying to implement a Stream encryption / decryption for XTEA. However, being a bit of a novice I am having trouble working out how I can pump the contents of a stream to / from the XTEA functions. Typical usage:

Nice piece of code, thank you for sharing it. I am able to encrypt/decrypt files on both the Windows Desktop and the Pocket PC device successfully, but continue to struggle with transferring files between desktop and a device and decrypting the corresponding encrypted file. I'm using a binary reader/writer to read/write strings into/from your TeaCrypto code. I feel it may be in the encoding between the devices, or possibly the choice of reader but have not hit upon the magic bullet. Have you been able to perform encryption/decryption between devices successfully? Thanks.

I'm having the same problem, thing is the encryption process builds a carriage return into the string and when you want to access a text file with the encrypted string in it you will read only till that carriage return.

So it will never work hmmm... :/

I tried all streams available in the .net framework and it doesnt work!!! it always reads till thet same character, You might try making a small application for the pocket pc which encrypts the strings and inserts them into an sqlCE DB and from there read and decrypt.

This is true, but I am also taking advantage of the ASCII class. Since ASCII chars are 1 byte in length this is not a problem. This code could be modified to take advantage of unicode. Thanks for the comments!

You're using System.Text.ASCIIEncoding.ASCII.GetBytes to convert from Chars to ASCII. If I understand ASCIIEncoding correctly, not only does this truncate your Chars to one byte, it actually truncates them to 7 bits... meaning that your code not only doesn't work with international strings, it doesn't even work with Latin strings (so you can't use accents or common English symbols like £)

I believe all this will be fixed if you switch from ASCIIEncoding to UTF8Encoding, but remember that the Length of the array might turn out longer than the length of the original string.

Before you implement an algorithm, it would be wise to check out if there exists known attacks against it.A description can be found in this paper: http://www.cs.berkeley.edu/~daw/papers/keysched-icics97.psThis report includes an appendix with an "Improved Attack on TEA" requiring only 2^23 chosen-plaintexts and one related key query. And 2^23 is a *small* number when speaking of attacks on symmetric ciphers.

Thanks for the information. I was not aware that any crypto analysis existed for this algorithm. What do you think about XTEA? I hear that it fixes problems that were found in the original implementation. My goal is to provide a small, fast algorithm that is easy to port to multiple platforms.

As has been pointed out, TEA has a couple of known weaknesses, and even though the attacks aren't very practical it's reason enough to prefer XTEA. However, neither cipher has been analysed as thoroughly as other algorithms. Is the AES (Advanced Encryption Standard) not suitable for this framework?

If you're interested, I've been writing some notes on the TEA/XTEA algorithms recently;HTML<a href="http://www-users.cs.york.ac.uk/~matthew/TEA.ps.gz"Gzipped Postscript

Thanks for the information. I have just updated the article to use the XTEA algorithm. I realize that TEA has its weaknesses and it has not been through the rigors of other algorithms, but I feel that this algorithm could easily deter the casual snooper and it is also portable and easy to implement. I am going to be working on another algorithm that implements a stronger encryption scheme shortly. Thanks for your feedback!

Cool. One other thing you might want to watch out for is what mode the cipher is used in. I don't know any C#, but it looks like you're using ECB mode. ECB is OK for some tasks, but most of the time you want to use a different mode to remove global patterns; have a look at this wikipedia article for a good example why this is needed (and a good explanation too!).

That's because the decrypt message is actually decrypting the contents of the cipher string variable. Textboxes are not capable of storing all characters in a string and therefore will be omitted when you set certain strings to textboxes. The encrypted textbox is just a "visual" of the data. This is why are you able to change the encrypted message and it still decrypts the same message. Sorry for the confusion.

This is some nice code, however here is yet another 'but'. You optionally append a space at the end of the source string before encryption, and trim the resulting string after decryption. This works fine, but does limit the content you can encrypt. If for whatever reason you need to encrypt something that ends in a space and is not even in length, the result of source->encrypt->decrypt would not be the exact same as the source string.

This can be solved by somehow adding the length of the source string into the array that is to be encrypted. Maybe you could always add a pair of ints that contain the length, or one that contains the length and another with random data (for security reasons?).

I've been playing around with encryption for an application I'm developing, and I've ran into this problem myself. I think it is important for encryption code to always return exactly what you feed it. So be aware of the possibility!

It is a nice piece of code though! Therefore this is not meant as negative feedback...

Something else, did you find anything about rights to use the algorithm? That might be an issue in commercial applications.

You are right, I was thinking about this when I was writing this article. I like your idea about appending the length of the string to the end of the string before encrypting. I will look into this. I am not too happy about the trim being there now.