Click here to Skip to main content
11,502,845 members (40,804 online)
Click here to Skip to main content

A C++ Implementation of the Rijndael Encryption/Decryption method

, 7 Nov 2002 Ms-PL 576.2K 16.1K 164
Rate this:
Please Sign up or sign in to vote.
An article presenting a C++ implementation of the Rijndael (AES) encryption/decryption method.

Introduction

Rijndael (pronounced rain-dahl) is the block cipher algorithm that has been selected by the U.S. National Institute of Standards and Technology (NIST) as the candidate for the Advanced Encryption Standard (AES). It was selected by contest from a list of five finalists, that were themselves selected from an original list of more than 15 submissions. Rijndael will begin to supplant the Data Encryption Standard (DES) - and later Triple DES - over the next few years in many cryptography applications. The algorithm was designed by two Belgian cryptologists, Vincent Rijmen and Joan Daemen, whose surnames are reflected in the cipher's name. Rijndael has its origins in Square, an earlier collaboration between the two cryptologists.

The cipher has a variable block length and key length. The authors currently specify how to use keys with a length of 128, 192 or 256 bits, to encrypt blocks with a length of 128, 192 or 256 bits (all nine combinations of key length and block length are possible). Both block length and key length can be extended very easily to multiples of 32 bits. Documentation and complete specification of the method (as required by NIST) can be found here.

Rijndael can be implemented very efficiently on a wide range of processors and in hardware. This C++ implementation presented here is based on the Java implementation used with the Cryptix toolkit found on the Internet here (Java code authors are Raif S. Naffah and Paulo S.L.M. Barreto). This implementation was tested against KAT test published by the authors of the method and the results were identical.

Implementation

The public user interface of the CRijndael class is given below:

class CRijndael
{
public:
  //Operation Modes
  enum { ECB=0, CBC=1, CFB=2 };

  //CONSTRUCTOR
  CRijndael();

  //DESTRUCTOR
  virtual ~CRijndael();

  //Expand a user-supplied key material into a session key.
  void MakeKey(char const* key, char const* chain, 
    int keylength=DEFAULT_BLOCK_SIZE, 
    int blockSize=DEFAULT_BLOCK_SIZE);

  //Encrypt exactly one block of plaintext.
  void EncryptBlock(char const* in, char* result);

  //Decrypt exactly one block of ciphertext.
  void DecryptBlock(char const* in, char* result);

  //Encrypt a larger block of data
  void Encrypt(char const* in, char* result, size_t n, int iMode=ECB);

  //Decrypt a larger block of data
  void Decrypt(char const* in, char* result, size_t n, int iMode=ECB);

  //Get Key Length
  int GetKeyLength();

  //Block Size
  int GetBlockSize();

  //Number of Rounds
  int GetRounds();

  //Resets chain block to initial chain block.
  void ResetChain();

  //Null chain block
  static char const* sm_chain0;
};

The MakeKey() function is used to expand a user-supplied key material into a session key and to initialize the chain block. The keylength and blockSize can be any combination of 16, 24 or 32 bytes sizes with DEFAULT_BLOCK_SIZE being 16. This function has to be called after construction before any other functions.

The EncryptBlock() function is used to encrypt a block of the specified size using the specified key.

The DecryptBlock() function is the reverse of the EncryptBlock() function and is used to decrypt a block of the specified size using the specified key.

The Encrypt() function is used to encrypt larger blocks of data. The block size has to be a multiple of the method's block size. This function can operate in the following modes: ECB, CBC or CFB. ECB mode is not using chaining. If the same block is encrypted twice with the same key, the resulting ciphertext blocks are the same. In CBC mode, a ciphertext block is obtained by first XORing the plaintext block with the previous ciphertext block, and encrypting the resulting value. In CFB mode, a ciphertext block is obtained by encrypting the previous ciphertext block and XORing the resulting value with the plaintext. The operation mode is specified in the iMode parameter with ECB being the default value.

The Decrypt() function is the reverse of the Encrypt() function.

The purposes of the other functions are obvious.

Use Examples

The use of CRijndael class is very easy. In the first code snippet example, a block and key size of 16 bytes are applied to a 16 bytes block. The initial chain block is a null block. The block "aaaaaaaabbbbbbbb" is encrypted and then decrypted back.

try
{
  char szHex[33];

  //Initialization
  CRijndael oRijndael;
  oRijndael.MakeKey("abcdefghabcdefgh", CRijndael::sm_chain0, 16, 16);

  char szDataIn[] = "aaaaaaaabbbbbbbb";
  char szDataOut[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

  //Encryption
  oRijndael.EncryptBlock(szDataIn, szDataOut);

  CharStr2HexStr((unsigned char*)szDataIn, szHex, 16);
  cout << szHex << endl;
  CharStr2HexStr((unsigned char*)szDataOut, szHex, 16);
  cout << szHex << endl;
  memset(szDataIn, 0, 16);

  //Decryption
  oRijndael.DecryptBlock(szDataOut, szDataIn);

  CharStr2HexStr((unsigned char*)szDataIn, szHex, 16);
  cout << szHex << endl;
}
catch(exception& roException)
{
  cout << roException.what() << endl;
}

In the next code snippet example, a block and key size of 16 bytes are applied to a larger block of data of size 48 bytes (the block of data size should be a multiple of the block size). The initial chain block is a null block. The block "ababababccccccccababababccccccccababababcccccccc" is encrypted and then decrypted back in all the operation modes (ECB, CBC and CFB).

try
{
  CRijndael oRijndael;
  oRijndael.MakeKey("1234567890123456", CRijndael::sm_chain0, 16, 16);
  char szDataIn1[49] = "ababababccccccccababababccccccccababababcccccccc";
  char szDataIn[49];
  char szDataOut[49];
  memset(szDataIn, 0, 49);
  memset(szDataOut, 0, 49);

  //Test ECB
  strcpy(szDataIn, szDataIn1);
  memset(szDataOut, 0, 49);
  oRijndael.Encrypt(szDataIn, szDataOut, 48, CRijndael::ECB);
  memset(szDataIn, 0, 49);
  oRijndael.Decrypt(szDataOut, szDataIn, 48, CRijndael::ECB);

  //Test CBC
  oRijndael.ResetChain();
  strcpy(szDataIn, szDataIn1);
  memset(szDataOut, 0, 49);
  oRijndael.Encrypt(szDataIn, szDataOut, 48, CRijndael::CBC);
  memset(szDataIn, 0, 49);
  oRijndael.ResetChain();
  oRijndael.Decrypt(szDataOut, szDataIn, 48, CRijndael::CBC);

  //Test CFB
  oRijndael.ResetChain();
  strcpy(szDataIn, szDataIn1);
  memset(szDataOut, 0, 49);
  oRijndael.Encrypt(szDataIn, szDataOut, 48, CRijndael::CFB);
  memset(szDataIn, 0, 49);
  oRijndael.ResetChain();
  oRijndael.Decrypt(szDataOut, szDataIn, 48, CRijndael::CFB);
}
catch(exception& roException)
{
  cout << "Exception: " << roException.what() << endl;
}

I am interested in any opinions and new ideas about this implementation. The project AES.zip attached to this article is including the source code of the presented CRijndael class and a test code.

History

  • 8 Nov 2002 - updated download.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

George Anescu
Web Developer
Romania Romania
No Biography provided

Comments and Discussions

 
QuestionPadding error with CBC mode in vc++ Pin
Member 1110607219-Mar-15 22:35
memberMember 1110607219-Mar-15 22:35 
BugVS2012 Error's Pin
Member 1065708317-Feb-15 20:43
memberMember 1065708317-Feb-15 20:43 
Questioncompile error Pin
Member 777178619-Sep-13 7:08
memberMember 777178619-Sep-13 7:08 
AnswerRe: compile error Pin
rasteron@live.com19-Sep-13 15:32
memberrasteron@live.com19-Sep-13 15:32 
GeneralPlease change the default mode away from ECB (security issue with default values!) Pin
Seikilos16-Sep-13 23:30
memberSeikilos16-Sep-13 23:30 
QuestionHow to encrypt a wide char (UTF -16) array? Pin
Michael B Pliam22-Jun-13 20:37
memberMichael B Pliam22-Jun-13 20:37 
QuestionSo many issues in the code than anyone could even think! Pin
arvin8teen10-Jan-13 19:00
memberarvin8teen10-Jan-13 19:00 
AnswerRe: So many issues in the code than anyone could even think! Pin
Nah Naho7-Aug-14 12:21
memberNah Naho7-Aug-14 12:21 
Questionportability between Linux and Windows? Pin
Spike!14-Jun-12 12:24
memberSpike!14-Jun-12 12:24 
QuestionProblem with control characters? Pin
JasonSTAL30-Jul-11 15:26
memberJasonSTAL30-Jul-11 15:26 
GeneralDoesn't work on Japanese OS Pin
rajeshb7927-Jul-11 6:14
memberrajeshb7927-Jul-11 6:14 
GeneralDoes Rijndael only work on ascii text? Pin
Spike!14-Jun-12 12:25
memberSpike!14-Jun-12 12:25 
Generalhow to work if i have rijndale 256? Pin
Fmeli8-Jun-11 4:08
memberFmeli8-Jun-11 4:08 
Generalinteroperability with openssl Pin
jogad5-Mar-11 4:18
memberjogad5-Mar-11 4:18 
Questionhelp: what are the arrays: sm_T1 sm_T2 sm_T3 sm_T4...... sm_U1... sm_U4? Pin
Kalmah18-Feb-11 22:48
memberKalmah18-Feb-11 22:48 
GeneralHelp, point..... Pin
phuctt17-Aug-10 22:15
memberphuctt17-Aug-10 22:15 
GeneralRe: Help, point..... [modified] Pin
Bkg6-Oct-10 5:19
memberBkg6-Oct-10 5:19 
GeneralRe: Help, point..... Pin
John Tan Jin Kiat23-Jan-11 20:19
memberJohn Tan Jin Kiat23-Jan-11 20:19 
GeneralMy vote of 3 Pin
mod16016-Aug-10 10:05
membermod16016-Aug-10 10:05 
GeneralAES Mode ECB encryption result not compatible with JCE AES Pin
ali_alaoui4-Oct-08 11:30
memberali_alaoui4-Oct-08 11:30 
GeneralRe: AES Mode ECB encryption result not compatible with JCE AES Pin
Umut Simsekli4-Mar-09 23:50
memberUmut Simsekli4-Mar-09 23:50 
QuestionHave a Bug!!! Pin
shycoffee19-Sep-08 23:17
membershycoffee19-Sep-08 23:17 
AnswerRe: Have a Bug!!! Pin
duanfh8208-Nov-09 21:40
memberduanfh8208-Nov-09 21:40 
QuestionHave a Bug!!! Pin
shycoffee19-Sep-08 23:15
membershycoffee19-Sep-08 23:15 
QuestionBinary files (images) Pin
seva.feldman20-Jul-08 5:04
memberseva.feldman20-Jul-08 5:04 
GeneralMy string is not a multiple of 16! Pin
mark-w3-Jan-08 17:19
membermark-w3-Jan-08 17:19 
GeneralRe: My string is not a multiple of 16! Pin
leedemon13-Mar-08 16:52
memberleedemon13-Mar-08 16:52 
QuestionRe: My string is not a multiple of 16! Pin
skyzhao26-Nov-09 18:33
memberskyzhao26-Nov-09 18:33 
AnswerRe: My string is not a multiple of 16! Pin
PauloProenca10-Sep-10 5:30
memberPauloProenca10-Sep-10 5:30 
QuestionSecurely Storing Key? Pin
brian257-Oct-07 4:55
memberbrian257-Oct-07 4:55 
AnswerRe: Securely Storing Key? Pin
neuroscript27-Nov-07 16:03
memberneuroscript27-Nov-07 16:03 
GeneralRe: Securely Storing Key? Pin
brian2528-Nov-07 5:22
memberbrian2528-Nov-07 5:22 
GeneralRe: Securely Storing Key? Pin
mark-w4-Jan-08 10:04
membermark-w4-Jan-08 10:04 
GeneralRe: Securely Storing Key? Pin
Member 381021130-Jul-08 12:48
memberMember 381021130-Jul-08 12:48 
GeneralDirectShow filter using your code Pin
Adofan5-Sep-07 1:31
memberAdofan5-Sep-07 1:31 
GeneralCompile error under UNICODE [modified] Pin
chocm4-Sep-07 0:42
memberchocm4-Sep-07 0:42 
GeneralPHP vs C++ Function Pin
ktwbc1-Aug-07 13:37
memberktwbc1-Aug-07 13:37 
GeneralPocketPC(Windows Mobile5.0) porting Pin
gauravzhere16-May-07 5:03
membergauravzhere16-May-07 5:03 
GeneralHelp Pin
kaunreeves5-May-07 6:35
memberkaunreeves5-May-07 6:35 
GeneralHelp Pin
kaunreeves5-May-07 6:35
memberkaunreeves5-May-07 6:35 
GeneralPossible Bug: Use of 't' and 'tt' in MakeKey Pin
rbid18-Feb-07 8:23
memberrbid18-Feb-07 8:23 
GeneralEncrypted Output Pin
kerrangster26-Jan-07 9:06
memberkerrangster26-Jan-07 9:06 
GeneralRe: Encrypted Output Pin
Podunk.vn@gmail.com1-Dec-09 8:43
memberPodunk.vn@gmail.com1-Dec-09 8:43 
GeneralDoubleBuffering Pin
mirano2-Jan-07 11:47
membermirano2-Jan-07 11:47 
Questiondifferences between gui and command line ? Pin
__TSX__15-Dec-06 8:58
member__TSX__15-Dec-06 8:58 
GeneralI am not getting Encrypted data properly Pin
Prashant_d049-Dec-06 23:31
memberPrashant_d049-Dec-06 23:31 
GeneralCFB mode not working Pin
Zamel5-Dec-06 20:46
memberZamel5-Dec-06 20:46 
GeneralRe: CFB mode not working Pin
Prashant_d049-Dec-06 23:33
memberPrashant_d049-Dec-06 23:33 
GeneralRe: CFB mode not working Pin
Zamel10-Dec-06 1:59
memberZamel10-Dec-06 1:59 
GeneralRe: CFB mode not working Pin
are_all_nicks_taken_or_what30-Aug-09 23:42
memberare_all_nicks_taken_or_what30-Aug-09 23:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 8 Nov 2002
Article Copyright 2001 by George Anescu
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid