0

I'm trying to create a long string that is produced out of encrypted substrings. For the encryption I'm using AES128 and libmcrypt. The code is working, but I get a shorter output then I should and a beeping sound. I guess it's because I'm using strlen, but I have no idea, how I can avoid that. I will be very grateful for some suggestions. Here is my code:

char *Encrypt( char *key, char *message){   
    static char *Res;
    MCRYPT mfd;
    char *IV;
    int i, blocks, key_size = 16, block_size = 16;
    blocks = (int) (strlen(message) / block_size) + 1;

    Res = calloc(1, (blocks * block_size));

    mfd = mcrypt_module_open(MCRYPT_RIJNDAEL_128, NULL, "ecb", NULL);
    mcrypt_generic_init(mfd, key, key_size, IV);

    strncpy(Res, message, strlen(message));
    mcrypt_generic(mfd, Res, block_size);
    //printf("the encrypted %s\n", Res);

    mcrypt_generic_deinit(mfd);
    mcrypt_module_close(mfd);

     return (Res);
}

char *mkline ( int cols) {
    int j;
    char seed[] = "thesecretmessage", key1[]="dontusethisinput", key2[]="abadinputforthis";

    char *encrypted, *encrypted2, *in = malloc(cols * 16);
    encrypted = Encrypt(key1, seed);
    sprintf(in, "%s", encrypted);
    encrypted2= Encrypt(key2, encrypted);
    printf("encrypted2 before for-loop %s\n", encrypted2);
    printf("encrypted2 before for loop len %d\n", strlen(encrypted2));
    for (j=1; j<cols; j++) {
        strcat(in, encrypted2);
        memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));
        printf("encrypted2 %s on position %d\n" , encrypted2,j);
        printf("encrypted2 len %d\n", strlen(encrypted2));
    }
    free(encrypted);
    free(encrypted2);
    return in;
}

int main(int argc, char *argv[]) {
    char *line = mkline(15);
    printf("line %s\n", line);
    printf("line lenght %d\n", strlen(line));
    return 0;
}
Gunther Struyf
  • 11,158
  • 2
  • 34
  • 58
user1656466
  • 145
  • 1
  • 9

4 Answers4

1

The encrypted string you are trying to print contains a stream of bytes where the value of the individual byte ranges from 0 to 255. Because you are using a cryptographically secure algorithm, the distribution of values is very close to even.

Since you are trying to print the encrypted string through a console, the console interprets some of the bytes as control characters (see Bell character) that are unprintable but have other effects instead, such as playing beeps.

Furthermore, strlen isn't doing what you think it should be doing because the encrypted string is not null-terminated, but instead contains zeroes amongst other bytes and they have no special meaning unlike in NULL terminated strings. You need to store the length of the string elsewhere.

otto
  • 1,138
  • 6
  • 14
  • Bytes don't rage 0..255, they are just bytes. It depends on the [tag:character-encoding] how they are printed. In most cases the least significant 7 bits form an ASCII encoded character, and that's where the control characters have been defined (and those are not used a lot anymore). – Maarten Bodewes Oct 12 '12 at 14:32
1

You get the beep sound because you are printing control character.

Also strlen return the size until the first '\0' character (because strings are zero terminated). That's why you get length less than you expect since the encrypted message may contain zeroes.

You can do something like this to return the result length:

 char *Encrypt(const char *key, const char *message, int *result_len)
 {
   *result_len = blocks * block_size;
 }

Also

memmove(encrypted2, Encrypt(key2, encrypted2),strlen(seed));

This line should produce a memory leak since every time you call Encrypt you call calloc (allocate new memory) which you need to free after you are done.

You probably should use memcpy, memmove is primarly used if there is a chance destination and source may overlap.

tozka
  • 3,211
  • 19
  • 23
  • Thank you all for the answers. I understand, that the problem is that the encrypted message may contain zeros ,but how can I keep those zeros in the string. I actuialy what to use the string for creating a random line in a picture later on, so I need that specific string with the specific length. I hope I managed to express my self clear enougth. Thanks! – user1656466 Oct 16 '12 at 12:36
  • Is there no posability to keep the zeros in my long string? As I wrote I want to use it later on and encrypt it. Thanks! – user1656466 Oct 18 '12 at 11:12
0

Simple, you are treating binary output (any byte value) directly as printable text. Any character wit a code point below 32 (hex 20) isn't. E.g. the ASCII value for BELL (look it up) could be meaningful to you. Print the resulting bytes in hexadecimals and you should be ok.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
0

I should like to add that in general it is good practice to clear any memory that held the plaintext/unencrypted message after you encrypt it if you can. This is not good coding practice, but good cryptology practice.

This can be done by: memset(buffer, 0, length_of_buffer);

Don't worry, that won't be optimized out by your compiler. It's actually not smart enough to tell if you'll be using that area again or not.

std''OrgnlDave
  • 3,912
  • 1
  • 25
  • 34