locked
AES string encryption in C++ RRS feed

  • Question

  • Can someone share a source code of AES-256 string (WCHAR) encryption / decryption?
    I really need it and couldn't go pass that MS Crypto API nonsense.

    Searched in many places, but I need a decent encryption / decryption function, which in not dependent on neither input nor key (password) length (must do the padding on its own).

    Please share Your knowledge. I have a nice idea for an app which I can't finish because of lack of simple 3 argument string enc/dec function in WM (like EncryptStr(WCHAR* in, WCHAR* key, WCHAR** out) and DecryptStr(WCHAR* in, WCHAR* key, WCHAR** out)).

    Thanks in advance.

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    Sunday, November 8, 2009 6:03 PM

Answers

  • Hi,

     

    I am not sure if C source code of aes implement is OK for you.

    Here is a link you can download an AES source

    http://www.cis.syr.edu/~wedu/seed/Labs/IPSec/files/libcrypt.tar

    The aes.c and aes.h in folder libcrypt are what we need. The aes_demo.c under demo folder gives us a demo how to use it.

    Now, we have everything we need. I create a Win32 console application say “aes256” targeting WM6 pro, add aes.h to header files and aes.c to source files.

    In aes256.cpp,

    extern "C"

    {

    #include "aes.h"

    }

    #include <string.h>

    #include <stdio.h>

    #include <windows.h>

    int _tmain(int argc, _TCHAR* argv[])

    {

        int n, i;

        aes_context ctx;

         WCHAR *in = TEXT("abc" );

         WCHAR *out;

         WCHAR *secret_key = TEXT("aa" );

        unsigned char buf[16];

    unsigned char key[32];

         memset(buf,0,16);

    memset(key,0,32);

         memcpy( buf, in, 16);

           /* Set the key */

           memcpy( key, secret_key, 32);

           aes_set_key( &ctx, key, 256);

          /* Encrypt */

           aes_encrypt( &ctx, buf, buf );

          /* Decrypt */

            aes_decrypt( &ctx, buf, buf );

           out=(WCHAR*)buf;

            return 0;

    }

    In the code, I did an encryption and a decryption.

    A little clarification, in the code I didn’t convert WCHAR* to unsigned char*, I just did a bit copy. I think it is up to you whether to do a real convert or not, the difference is the length of data to be encrypted.

    AES’s key size can be 128 bits, 192 bits, or 256 bits. Since you specify AES 256, I hard code the key size. Therefore if user passed a long key it will be cut, if short key it will be pad.

    The code above only supports 128bit of plaintext encryption which is a block cipher of AES algorithm. If your plaintext is more than that there are several ways(AES modes) to encrypt data, such as ECB (Electronic Code Book), CBC (Cipher Block Chaining), CFB (Cipher Feedback),

    For detail please refer to

    http://en.wikipedia.org/wiki/Cipher_Block_Chaining#Cipher-block_chaining_.28CBC.29

    And there are more codes need to be done.

     

    Hope this helps,

    Zhe Zhao

    • Marked as answer by Mal Loth Saturday, November 14, 2009 2:01 PM
    Wednesday, November 11, 2009 9:54 AM
  • Ok, I've finally managed to get it to work.
    Unfortunatelly Your code had also the same flaw - it included password in first encoded output.

    To prevent this from happening and further secure the string I had to use malloc and BYTE arrays instead of unsigned char predefined array.

    So now the final, working code looks like this:

    #include "stdafx.h"
    #include "aes.c"
    #include <windows.h>
    #include <commctrl.h>
    
    void _tmain(int argc, _TCHAR* argv[])
    {
    	aes_context ctx;
    	WCHAR* in = L"8790";
    	WCHAR* out;
    	WCHAR* key = L"0012a5d8aab12a01";
    
    	BYTE* buff = (BYTE*)malloc(16);
    	BYTE* keyBuff = (BYTE*)malloc(32);
    
    	memset(buff, 0, 16);
    	memset(keyBuff, 0, 32);
    
    	// allocating memory
    	memcpy(buff, in, wcslen(in) * 2);
    	memcpy(keyBuff, key, wcslen(key) * 2);
    	aes_set_key(&ctx, keyBuff, 256);
    
    	// enrypting
    
    	aes_encrypt(&ctx, buff, buff);
    	out = (WCHAR*)buff;
    	MessageBox(NULL, (WCHAR*)out, NULL, 0);		// output: ________
    	
    	// decrypting
    	aes_decrypt(&ctx, buff, buff);
    	out = (WCHAR*)buff;				// output: 8790
    	MessageBox(NULL, (WCHAR*)out, NULL, 0);
    
    	free(buff);
    	free(keyBuff);
    }

    Thanks for Your help ZHE ZHAO. 
    I really appreciate it.

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Marked as answer by Mal Loth Saturday, November 14, 2009 2:01 PM
    Saturday, November 14, 2009 2:00 PM

All replies

  • Hi,

     

    I am not sure if C source code of aes implement is OK for you.

    Here is a link you can download an AES source

    http://www.cis.syr.edu/~wedu/seed/Labs/IPSec/files/libcrypt.tar

    The aes.c and aes.h in folder libcrypt are what we need. The aes_demo.c under demo folder gives us a demo how to use it.

    Now, we have everything we need. I create a Win32 console application say “aes256” targeting WM6 pro, add aes.h to header files and aes.c to source files.

    In aes256.cpp,

    extern "C"

    {

    #include "aes.h"

    }

    #include <string.h>

    #include <stdio.h>

    #include <windows.h>

    int _tmain(int argc, _TCHAR* argv[])

    {

        int n, i;

        aes_context ctx;

         WCHAR *in = TEXT("abc" );

         WCHAR *out;

         WCHAR *secret_key = TEXT("aa" );

        unsigned char buf[16];

    unsigned char key[32];

         memset(buf,0,16);

    memset(key,0,32);

         memcpy( buf, in, 16);

           /* Set the key */

           memcpy( key, secret_key, 32);

           aes_set_key( &ctx, key, 256);

          /* Encrypt */

           aes_encrypt( &ctx, buf, buf );

          /* Decrypt */

            aes_decrypt( &ctx, buf, buf );

           out=(WCHAR*)buf;

            return 0;

    }

    In the code, I did an encryption and a decryption.

    A little clarification, in the code I didn’t convert WCHAR* to unsigned char*, I just did a bit copy. I think it is up to you whether to do a real convert or not, the difference is the length of data to be encrypted.

    AES’s key size can be 128 bits, 192 bits, or 256 bits. Since you specify AES 256, I hard code the key size. Therefore if user passed a long key it will be cut, if short key it will be pad.

    The code above only supports 128bit of plaintext encryption which is a block cipher of AES algorithm. If your plaintext is more than that there are several ways(AES modes) to encrypt data, such as ECB (Electronic Code Book), CBC (Cipher Block Chaining), CFB (Cipher Feedback),

    For detail please refer to

    http://en.wikipedia.org/wiki/Cipher_Block_Chaining#Cipher-block_chaining_.28CBC.29

    And there are more codes need to be done.

     

    Hope this helps,

    Zhe Zhao

    • Marked as answer by Mal Loth Saturday, November 14, 2009 2:01 PM
    Wednesday, November 11, 2009 9:54 AM
  • Thanks ZHE ZHAO :). 
    I'll try it and post as soon as I'll get it to work.

    Best regards,
    ML

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    Wednesday, November 11, 2009 11:17 AM
  • Unfortunately this method is not safe for encrypted word storing.
    When I do something like this:

    aes_context ctx;
    WCHAR* in = L"1234";
    WCHAR* out;
    WCHAR* key = L"1234abcd";
    
    unsigned char buff[16];
    unsigned char keyBuff[32];
    
    memset(buff, 0, 16);
    memset(keyBuff, 0, 32);
    
    // allocating memory
    memcpy(buff, in, wcslen(in) * 2);
    memcpy(keyBuff, key, wcslen(key) * 2);
    aes_set_key(&ctx, keyBuff, 256);
    
    // enrypting
    aes_encrypt(&ctx, buff, buff);
    out = (WCHAR*)buff;
    MessageBox(NULL, out, NULL, 0);		// output: ________1234abcd
    	
    // decrypting
    aes_decrypt(&ctx, buff, buff);
    out = (WCHAR*)buff;					// output: 1234
    MessageBox(NULL, out, NULL, 0);

    I got my password in first output. I need to store encrypted input for later usage and I can't show the password with it. Any suggestions on what's wrong?

    This is what I want to achieve:

    - get storage card id; (no problem)
    - get encrypted PIN code from the registry; (no problem)
    - if (there's none) { show user an input box where he will be able to input his SIM card PIN; encrypt it wth CID; store it in the registry; }
    - else { decrypt ecrypted PIN by usage of storage card ID; use the PIN to unlock the phone; }

    This app will be started at WM boot time and will auto-unlock Your phone if there's proper SD card in the slot.
    But I'm unable to find a simple encryption / decryption algorithm that would suit my needs!

    Please help!



    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    Wednesday, November 11, 2009 11:49 AM
  • Hi Mal Loth,

    I tried your plaintext and key, in my test the encrypted "out" seems to be correct. It shows some unrecognized characters, not the original key. Since you can get the plaintext through decrypt, please try to maybe run debug step by step to figure out the problem.
    I find my code is not correct, your way of padding is correct.

    In addition, hope the following assists you.
    Based on my understanding, AES requires the plain text to be 128 bit which is a fixed block size of AES.

    http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
    If your plaintext is more than 128 bit. You can use AES-CBC or AES-CFB or…

    AES-CBC requires that data must be encrypted as data chunk with 16 bytes unit. If the data is not multiple of 16, we need to pad the data. AES-CFB does not require padding.

    See this for detail

    http://en.wikipedia.org/wiki/Cipher_Block_Chaining

    let me know if there is further issue.
    Zhe Zhao

     

    Thursday, November 12, 2009 3:34 AM
  • I wonder what can be the problem, because the whole logic is ok.
    I'm using 4-8 WCHARs (8-16 bytes) so I'm won't exceed the 16 bytes limit.

    I couldn't attach the header and I just included "aes.c" inside my C++ code.
    Can that be a problem?

    Nevertheless, I'll be still trying to solve the matter because I have enough of PIN code entering (can't disable it in Settings).

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    Thursday, November 12, 2009 7:09 AM
  • Hi,

     

    I posted my project here.

    http://cid-587100d207ba0ef7.skydrive.live.com/self.aspx/.Public/aes256.zip

     

    Hope it helps,

    Zhe Zhao

    • Proposed as answer by RKVRamesh Wednesday, March 6, 2013 9:12 AM
    • Unproposed as answer by RKVRamesh Wednesday, March 6, 2013 9:12 AM
    Thursday, November 12, 2009 8:37 AM
  • Ok, I've finally managed to get it to work.
    Unfortunatelly Your code had also the same flaw - it included password in first encoded output.

    To prevent this from happening and further secure the string I had to use malloc and BYTE arrays instead of unsigned char predefined array.

    So now the final, working code looks like this:

    #include "stdafx.h"
    #include "aes.c"
    #include <windows.h>
    #include <commctrl.h>
    
    void _tmain(int argc, _TCHAR* argv[])
    {
    	aes_context ctx;
    	WCHAR* in = L"8790";
    	WCHAR* out;
    	WCHAR* key = L"0012a5d8aab12a01";
    
    	BYTE* buff = (BYTE*)malloc(16);
    	BYTE* keyBuff = (BYTE*)malloc(32);
    
    	memset(buff, 0, 16);
    	memset(keyBuff, 0, 32);
    
    	// allocating memory
    	memcpy(buff, in, wcslen(in) * 2);
    	memcpy(keyBuff, key, wcslen(key) * 2);
    	aes_set_key(&ctx, keyBuff, 256);
    
    	// enrypting
    
    	aes_encrypt(&ctx, buff, buff);
    	out = (WCHAR*)buff;
    	MessageBox(NULL, (WCHAR*)out, NULL, 0);		// output: ________
    	
    	// decrypting
    	aes_decrypt(&ctx, buff, buff);
    	out = (WCHAR*)buff;				// output: 8790
    	MessageBox(NULL, (WCHAR*)out, NULL, 0);
    
    	free(buff);
    	free(keyBuff);
    }

    Thanks for Your help ZHE ZHAO. 
    I really appreciate it.

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Marked as answer by Mal Loth Saturday, November 14, 2009 2:01 PM
    Saturday, November 14, 2009 2:00 PM
  • Zhe Zhao

    Link is saying.. 

    This item might not exist or is no longer available

    Much appropriated your help to have it again.

    Many Many Thanks in advance & response!!!


    Ramesh Kumar Verma

    Wednesday, March 6, 2013 9:13 AM
  • Link is not working..Please re-post if possible.
    Friday, December 14, 2018 8:46 AM