Game Development Community

dev|Pro Game Development Curriculum

Adding Simple AES Encryption for Data files (Updated 1/16)

by Kevin Mitchell · 01/09/2013 (9:38 pm) · 25 comments

This shows you how to implement a simple object that uses, Rijndael's AES encryption. I know that AES is used somewhere in the engine already but for those that just wants a clean simple API here is one.

Click Here

Instructions

1.Extract to Engine/Source/rpg_engine/
Quote:
Note you can put it any where but I'm following my path structure.

2. Open the engine code and add a filter folder "rpg_engine"
3. Open the engine code and add a filter folder inside of "rpg_engine" called "AES"
4. Click add add Existing Files.
5. Add the Rijndael.cpp,Rijndael.h,SimpleAES.cc, and SimpleAES.h.
6. Compile
7. Add the following test to your code.

function testAES(){
  new SimpleAES(StringCrypt){
  };


   echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
   echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
   echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
   echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
   echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
   %readFile = new FileObject();
   %path="toEncrypt.txt";
   if(%readFile.openForRead(%path)){
      while(!%readFile.isEOF()){  
         %source=%readFile.readLine();
         echo("1: "@%source);
         %cryptString=StringCrypt.cryptLine(%source);
         //echo("2: "@%cryptString);
         %results=StringCrypt.decryptLine(%cryptString);
         //echo("3: "@%results);
         if(!(%source $= %results)){
            %readFile.close();
            %readFile.delete();
            echo("ERRROR ENCRYPTING: "@%source);
            return;
         }
      }
      %readFile.close();
      %readFile.delete();
   }else{
      %readFile.delete();
      echo("FILE COULD NOT BE OPENED");
   }
   
   %testChars="! Q A Z W S X # E D C $ R F V % T G B ^ Y H N & U J M * I K < > ( O L > ) P : ? _ { + } | 1 q a z 2 w s x 3 e d c 4 r f v 5 t g b 6 y h n 7 u j m 8 i k , 9 o l . 0 p ; / - [ ' = ] ` ~"; 
   %randomChar=getWord(%testChars,getRandom(0,getWordCount(%testChars)));
   while(strlen(%randomChar)<(512)){  
      %source=%randomChar=%randomChar@getWord(%testChars,getRandom(0,getWordCount(%testChars)));
      //echo("1: "@%source);
      %cryptString=StringCrypt.cryptLine(%source);
      //echo("2: "@%cryptString);
      %results=StringCrypt.decryptLine(%cryptString);
      //echo("3: "@%results);
      if(!(%source $= %results)){
         echo("ERRROR ENCRYPTING: "@%source);
         return;
      }
   }
   
  EncryptFile("toEncrypt.txt","toEncrypt.txt.bin");
  DeCryptFile("toEncrypt.txt.bin","NewtoEncrypt.txt");
  echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
  echo(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
}


function createAES(){
   if(isObject(StringCrypt))StringCrypt.delete();
   new SimpleAES(StringCrypt){
   };
}

function encrypt(%source){
  %cryptString=StringCrypt.cryptLine(%source);
  return %cryptString;
}

function decrypt(%source){
  %cryptString=StringCrypt.decryptLine(%source);
  return %cryptString;
}


function EncryptFile(%path,%savePath){
  //Might want to change the name of the CryptObject in your release
  if(isObject(StringCrypt))StringCrypt.delete();
  new SimpleAES(StringCrypt){
  };

   %readFile = new FileObject();
   %writeFile = new FileObject();
   
   if(%readFile.openForRead(%path)){
      if(%writeFile.openForWrite(%savePath)){
         while(!%readFile.isEOF()){  
            %source=%readFile.readLine();
            %cryptString=StringCrypt.cryptLine(%source);
            %results=StringCrypt.decryptLine(%cryptString);
            if(!(%source $= %results)){
               echo("ERRROR ENCRYPTING: "@%source);
               %writeFile.close();
               %writeFile.delete();
               %readFile.close();
               %readFile.delete();
               return false;
            }else{
               %writeFile.writeLine(%cryptString);
            }
         }
         %writeFile.close();
         %writeFile.delete();
         %readFile.close();
         %readFile.delete();      
      }else{
         %writeFile.close();
         echo("FILE COULD NOT BE CREATED");
         return false;
      }
   }else{
      %readFile.delete();
      echo("FILE COULD NOT BE OPENED");
      return false;
   }
   return true;
}

//Might not want to include this in the release code
function DeCryptFile(%path,%savePath){
  if(isObject(StringCrypt))StringCrypt.delete();
  new SimpleAES(StringCrypt){
  };

   %readFile = new FileObject();
   %writeFile = new FileObject();
   
   if(%readFile.openForRead(%path)){
      if(%writeFile.openForWrite(%savePath)){
         while(!%readFile.isEOF()){  
            %source=%readFile.readLine();
            %results=StringCrypt.decryptLine(%source);
            %writeFile.writeLine(%results);
         }
         %writeFile.close();
         %writeFile.delete();
         %readFile.close();
         %readFile.delete();      
      }else{
         %writeFile.close();
         echo("FILE COULD NOT BE CREATED");
         return false;
      }
   }else{
      %readFile.delete();
      echo("FILE COULD NOT BE OPENED");
      return false;
   }
   return true;
}
//Uncomment to do test encryption
//testAES();


Notes: You might want to make your own random key. To do this open SimpleAES.cc.

Change the Key[].

Note that the key is currently the highest key avaliable whish is 32 bytes aka 256 bit encryption.
Make sure you change the key to exactly 32 characters.

If you change the key to something lower make sure its 16, 24 and 32 only. And if you change it lower change the #define CRYPTSIZE too.

#define CRYPTSIZE 32
char Key[]=&amp;quot;1qaz2wsx3edc4rfv5tgb6yhn7ujm8ik9&amp;quot;;


You can now save data to a file in an encrypted state and not just have raw text in a text file.

When loading the line from file make sure you decrypt it before using the data.

Happy Coding.


Edited 1/16/2013:

Added the base64 encoding for pure string return. Before I was sending just the encrypted data that is just a binary array and can have null byte causing issues with the return string. Now the encrypted data is using the Base64 code to give an encoded string.


PS: Richard Marrevee thank you for your assistance with the data file.
Page«First 1 2 Next»
#21
02/05/2013 (7:28 pm)
This looks interesting. Been looking for some easy AES Encryption for passwords.

Thanks, Kevin


#22
02/06/2013 (6:13 pm)
This works for me. Here is a quick test I did.


Compile the source.

Put these two functions in a new file and call it aes.cs
game/scripts/server

Make sure to exec it in scriptExec.cs


function encrypt(%source)
{
  new SimpleAES(StringCrypt){  
  }; 

  %cryptString = StringCrypt.cryptLine(%source);
  StringCrypt.delete();

  return %cryptString;
}



function decrypt(%source)
{
  new SimpleAES(StringCrypt){  
  }; 

  %cryptString = StringCrypt.decryptLine(%source);
  StringCrypt.delete();

  return %cryptString;
}



Put this at the bottom in commands.cs
game/scripts/server

function serverCmdDecryptData(%client, %val)
{

    echo("--------------------------------------------");

    echo("Received data: " @ %val);

    echo("--------------------------------------------");

    echo("--");


    %data = decrypt(%val);
 
    echo("--------------------------------------------");

    echo("Decrypted data: " @ %data);

    echo("--------------------------------------------");


}



I created new file called commands.cs
Placed it in game/scripts/client

Make sure to exec it in init.cs

Add the following code to the file

function EncryptData()
{
    %source = "foobar";
 
    %data = encrypt(%source);

    commandToServer('DecryptData', %data);

}



Then add this to default.bind.cs

moveMap.bindCmd(keyboard, n, "EncryptData();", "");




Console log output

Activating DirectInput...
*** Control Object Changed
Mapping string: Red to index: 16
Mapping string: setNumericalHealthHUD to index: 17
Mapping string: DecryptData to index: 3
--------------------------------------------
Received data: PczF7F/SfuFaqZNBHYGNn80zMQg+wHaEfCOsi6axQOk=
--------------------------------------------
--
--------------------------------------------
Decrypted data: foobar
--------------------------------------------
*** ENDING MISSION
4837 -> deactivatePackages
CDROP: 4839 IP:0.0.0.0:0
Exporting server prefs...
Exporting server prefs...


#23
02/06/2013 (6:43 pm)
Never thought of making so you can encrypt data that comes and goes to the server. nice.
#24
02/06/2013 (7:16 pm)
Yeah, this is really cool. I'm going to test this on arrays past to the server. I don't think I can encrypt an array as a whole, may need to encrypt each string as the array is assembled.

I digg stuff like this.

#25
02/06/2013 (8:27 pm)
AES i built to encrypt bytes but I do not know a BYTE data type that is sent into the engine. If you know one you can duplicate the encrypt and decrypt functions and replace the string table with the byte array structure. You still will have to pad the bytes to an even block
Page«First 1 2 Next»