Search code examples
c++encryptionopensslaes

can't show the encrypted text on Logcat


main func to try encrypt and show on logcat

aes = new ofxLibcrypto();
// start
unsigned char *key = (unsigned char *)"qwertyuiqwertyuiqwertyuiqwertyui";
unsigned char *iv = (unsigned char *)"qwertyuiqwertyui";
unsigned char *plaintext = (unsigned char *)"The quick brown fox jumps over the lazy dog";
unsigned char *ciphertext;
unsigned char decryptedtext[128];
int ciphertext_len, decryptedtext_len;
ciphertext_len = aes->encrypt(plaintext, strlen((char*)plaintext), key, iv, ciphertext);


ofLogNotice("IDB") << "Encrpyted: " << ciphertext;


decryptedtext_len = aes->decrypt(ciphertext, ciphertext_len, key, iv, decryptedtext);
decryptedtext[decryptedtext_len] = (unsigned char) "\0";
ofLogNotice("IDB") << "Decrypted: " << decryptedtext;
// end

Program encrypts successfully but when I try to show the ciphertext, it shows only first char. When I try to show char by char in a loop, it shows all chars as encrypted. I examined many codes to fix it but they do it this way and I can't fix it. Since encrypting and decrypting functions works fine, I didn't attach them but if needed I will attach.

Thanks already who will help.


Solution

  • can't show the encrypted text

    Your encrypted text(ciphertext) is a binary blob. It may have some printable characters such as A or ? or something, but is also going to have characters that are not printable for e.g characters with ASCII value 1, 2, 3 or even 0.

    Consider this sequence of characters in a binary blob:

    unsigned char data[] = {0x41, 0x00, 0x42, 0x43};
                         // 'A',  '\0', 'B',  'C'
    

    data contains characters 'A', '\0'(null byte), 'B', 'C'. If you try to print data, you will only see A, because the next character is a null byte and it will stop printing immediately when it encounters that.

    So then, how do you display a binary blob? The usual way to do it is by encoding the binary data as either base16 or some other base.

    Here's a simple function to encode your data in base16:

    template <typename T>
    std::string toBase16(const T itbegin, const T itend)
    {
        std::string rv;
        static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        rv.reserve(std::distance(itbegin, itend) * 2);
        for (T it = itbegin; it < itend; ++it) {
            unsigned char val = (unsigned char)(*it);
            rv.push_back(hexmap[val >> 4]);
            rv.push_back(hexmap[val & 15]);
        }
        return rv;
    }
    

    Usage:

    int ciphertext_len, decryptedtext_len;
    ciphertext_len = aes->encrypt(plaintext, strlen((char*)plaintext), key, iv, ciphertext);
    
    ofLogNotice("IDB") << "Encrpyted: " << toBase16(ciphertext, ciphertext + ciphertext_len);
    

    Another way is to cast every byte to int and then display its decimal value:

    unsigned char data[] = {0x41, 0x00, 0x42, 0x43};
                         // 'A',  '\0', 'B',  'C'
    for (int i = 0; i < 4; ++i)
    {
        cout << static_cast<int>(data[i]) << ' ';
    }
    //Output: 65 0 66 67