Introduction
I have been involved in many projects and product developments in last 12
years. Most of the applications use some form of encryption. Even though it is
such important thing to choose right kind of algorithm, in most cases single
developer( whoever is responsible for that part of the project) makes all the decisions. The selection of right encryption
algorithm is over looked in most of
the projects( We may end of selecting the right one, but we won't know WHY ).
Since the computing power has increased so much in last few years, it is
vital for many applications to revisit the encryption algorithms. Using this
computing power, hackers can easily find the key combination in no time. It is
possible to search through all the possible DES keys in less then 24 hrs. Just
recently I read an article where they talk about increasing the integration
of transistors/PSI by 4-5 times the existing numbers. That means we will have,
even more computing power, that means DES keys can broken even faster.
Algorithm Selection Process
Many factors drive the selection of your encryption algorithm.
International laws
Make sure that, the country where this software will be used doesn't have any
restrictions.
CPU cycles
In some applications, we don't want the encryption/decryption to take up lot of
cycles. Good example would be 'embedded' applications. Such applications will
have limited computing power and less memory. Even in the server application,
we don't want CPU usage to be above some
threshold ( say 75%) for longer period of times. Consider a UDP packet
forwarding application which has a steady stream of UDP packets coming on one
port, if encryption algorithm takes up lot of CPU cycles, during the peak times,
we might see some weird problems.
The following table compares the CPU cycles used by some popular encryption
algorithms.
Ciper | Encrypt | Schedule |
RC6 | 105981 | 78808 |
Rijndael | 9464 | 0 |
TwoFish | 26500 | 1750 |
DES | 17458 | 12320 |
SHA | 67244 | 478 |
Memory requirements
This factor is critical for all the embedded applications. Make sure
that your encryption algorithm does not need lot of RAM ( and ROM ).
If you ever coded for those tiny boxes, you will understand the
acuteness of this problem. I remember my old days when I worked for
VeriFone developing software for their 390 terminals running QNX.
Just to make the stack as small as possible, we ended up having lot
global variables ( and of course code looked ugly).
And I know of one more company( I do not want to mention the name),
just because they can not encrypt the data due to lack of memory,
they transmit some sensitive information via plain text.
Those are all very typical problems faced my embedded developers.
Cost and Licensing
Most of the algorithms are 'royalty free'. But you have to clearly
understand the licensing agreements before you put them to use.
Code compactness
This factor too( like memory requirements) is critical for embedded
applications.
Code Samples
For my illustration purposes, I am going to use Rijndael. You can
find lot of information about this on internet. I am going to point
some valid reasons why I chose Rijndael for this illustration
purposes.
- It is one of the smallest and fastest cipher.
- It can be implemented in 64 bytes of RAM
- Rijndael, which would come in three different levels of
cryptographic strength, is expected to provide strong security for
20 to 30 years or longer.
- Even a machine capable of breaking the old DES standard in a
second would take some 149 trillion years to crack the proposed
AES's lowest level of security( According to - Mr. Jim Foti, a
mathematician)
Okay. It is for some code. Well, there are many implementations which
are available with source code. For those considering to use this
algorithm in an embedded application running OSs like VxWorks, ThreadX, pSOS,
embedded Linux should look into ANSI C implementations.
I am going to use Crypto++ 4.2 implementation in my example code. It is very
easy to build this library( I am using VS6 and VS7). There quite a bit of
information on this topic online.
Let us consider a small example in which UDP server multicasts its system
time. All the multicast clients read this time and set their time accordingly.
Source can be obtained from my article:
http://www.codeproject.com/useritems/IOCP-MULTICAST-UDP.asp
I am going to modify those server and client applications so that
the server encrypt the information using Rijndael and Client
decrypts it before displaying that time.
#include <rijndael.h>
static const BYTE *const key = (BYTE *)"0123456....000000";
void EncryptData(SYSTEMTIME& xSysTime)
{
CryptoPP::RijndaelEncryption rTest(key);
rTest.ProcessBlock((byte *)&xSysTime);
}
EncryptData(stSysTime);
nRet = sendto(hSocket,(char *)&stSysTime,
sizeof(stSysTime),0, (struct sockaddr*)&stDstAddr,
sizeof(stDstAddr));
BOOL HandleIncomingData( UCHAR* pBuf)
{
InterlockedIncrement(&nCount);
SYSTEMTIME *lpstSysTime;
lpstSysTime = (SYSTEMTIME *)(pBuf);
CryptoPP::RijndaelDecryption rTest(key);
rTest.ProcessBlock((BYTE *)lpstSysTime);
printf(
"[%d]UTC Time %02d:%02d:%02d:%03d on %02d-%02d-%d \n",
nCount, lpstSysTime->wHour,
lpstSysTime->wMinute, lpstSysTime->wSecond,
lpstSysTime->wMilliseconds, lpstSysTime->wMonth,
lpstSysTime->wDay, lpstSysTime->wYear);
memset(&pBuf,0,BUFSIZE);
return TRUE;
}
Conclusion
I did not discuss the key management in this article. Without safeguarding
your keys, encryption will be useless. SSL/TLS provides a good starting point
for you to to read about key management. It makes use of public-private keys to
establish the symmetric key. If you any have any comments or questions you can
email me at shapall@hotmail.com