How to use the AES class? [SOLVED]



  • On 01/03/2016 at 14:45, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:    
    Platform:      
    Language(s) :

    ---------
    So there is

    1. AES::Encrypt(void* pData, Int lDataLength, const void* pKey)
    2. AES::Decrypt(void* pData, Int lDataLength, const void* pKey)

    but the documentation is not very precise, or rather confusing to me. It says that we should pass
    a value computed with AES::CalcEncryptedDataSize() for "lDataLength", but how would it know
    the actual size of the data in "pData" then? And where is the encrypted version stored? I assume
    "pData" is the input and  output data?

    Also, for AES::Decrypt(), I don't see a way to find the length of the data after it has been decrypted.

    Could someone post an example please?

    Thanks,
    Niklas



  • On 02/03/2016 at 09:28, xxxxxxxx wrote:

    Hello,

    it seems that the documentation (and the pgp.cpp example) are outdated; some of the information in the documentation is no longer correct.

    From what I could learn I created this example, I hope it will help you.

      
    // plain text  
    const char plainText[] = "O brave new world That has such people in!";  
    const Int32 length = sizeof(plainText);  
      
    GePrint("Plain Text: " + String(plainText));  
      
    // secret key  
    char key[16];  
    MemCopy(key, "7c30e00bb6271495", 16);  
    const Int32 keyLength = sizeof(key) * 8;  // size in bit  
      
    // check key length  
    if (!((keyLength == 128) || (keyLength == 192) || (keyLength == 256)))  
      return false;  
      
    // block size in bit  
    const Int32 blockSize = 256;  
      
    // memory to store the encrypted data  
    void* data = nullptr;  
    Int   dataSize = 0;  
      
    // encrypt  
    {  
      // get size of the memory needed to store the encrypted data  
      dataSize = AES::CalcEncryptedDataSize(blockSize, length);  
      
      // allocate needed memory  
      data = NewMemClear(char, dataSize);  
      if (!data)  
      return false;  
      
      // copy the given text into the memory  
      CopyMem(plainText, data, length);  
      
      AutoAlloc<AES> aes;  
      if (aes && aes->Init(blockSize, keyLength))  
      {  
      aes->Encrypt(data, dataSize, key);  
      }  
    }  
      
    // decrypt  
    {  
      AutoAlloc<AES> aes;  
      if (data && aes && aes->Init(blockSize, keyLength))  
      {  
      if (aes->Decrypt(data, dataSize, key))  
      {  
        GePrint("Decrypted Data: " + String((char* )data));  
      }  
      }  
    }  
      
    DeleteMem(data);  
    

    AES is a block cipher. This means for every bit you put in you get one bit out. If only a part of the given (decrypted) data is usable data you could store the size of the usable data within the data block itself or you use something like a null-terminated string (as in the example).

    Best wishes,
    Sebastian



  • On 02/03/2016 at 22:41, xxxxxxxx wrote:

    Hey Sebastian, thanks a lot for the example! It's definitely helpful. Unless I'm blind, only one thing is
    missing from it. It doesn't show how I can find the size of the data after it is decrypted. What if I'm not
    working with a null-terminated string? Or do I need to keep track of the actual data size myself?

    There must be a way, otherwise it would be easy to make the program run into UB. Just give it an
    encrypted string full of random characters that you know will not decrypt into something that contains
    a null character, though your program assumes the decrypted data is a null-terminated string.

    Thanks!
    Niklas



  • On 03/03/2016 at 09:21, xxxxxxxx wrote:

    Hello,

    as stated above, AES is a block cipher. The size of the plain text is as big as the size of the encrypted data and as big as the size of the decrypted data. So if only a part of the whole memory block used is actual payload, you must come up with a way to find out which part.

    One way would be to store the size of the payload also in the memory block. This is done in the pgp.cpp example (see lines 185 and 234).

    best wishes,
    Sebastian



  • On 05/03/2016 at 12:05, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    as stated above, AES is a block cipher. The size of the plain text is as big as the size of the encrypted data and as big as the size of the decrypted data.

    I understand that much, but if that is the case, why would we need to use AES::CalcEncryptedDataSize()?
    AFAIK there is some encryption overhead to AES, so it's probably a constant overhead not depending
    on the input data size since you are saying that the size of the encrypted data is the same as the size
    of the input data. I just feel like the AES::CalcDecryptedDataSize() function is missing.

    Anyway, I didn't have time to look into the PGP example you linked, so looking into that might clear
    things up for me. Thanks for your help, Sebastian.

    Cheers,
    Niklas

    PS: For linking code on GitHub which might change in the future, it's useful to link a "constant" version
    of the code. You can press on "History" on top-right corner of the box that contains the file's code, then
    click the "<>" button of the most recent commit to go to the same file but with the commit SHA in the
    URL. So here's the link from above that will not change unless someone modifies the Git history or
    takes down the project. :)

    pgp.cpp:185-234



  • On 11/03/2016 at 08:09, xxxxxxxx wrote:

    Hello,

    as said, AES is a block cypher. It can only handle data blocks of certain sizes. So for example if AES would only handle blocks of the size 512 and you want to encrypt 1000 bits, CalcEncryptedDataSize() would return 1024 for 1000 bits; AES would not accept a block of 1000 bits but a block of 1024 bits.

    Best wishes,
    Sebastian


Log in to reply