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;
}
4

4 回答 4

1

您会听到哔声,因为您正在打印控制字符。

strlen返回大小直到第一个 '\0' 字符(因为字符串以零结尾)。这就是为什么你得到的长度比你预期的要少,因为加密的消息可能包含零。

您可以执行以下操作来返回结果长度:

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

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

这条线应该会产生内存泄漏,因为每次Encrypt您调用calloc(分配新内存)时,您都需要在完成后释放它。

您可能应该使用 memcpy,如果有机会目标和源可能重叠,则主要使用 memmove。

于 2012-10-12T11:25:37.197 回答
1

您尝试打印的加密字符串包含一个字节流,其中单个字节的值范围从 0 到 255。因为您使用的是加密安全算法,所以值的分布非常接近均匀。

由于您尝试通过控制台打印加密字符串,因此控制台将某些字节解释为不可打印但具有其他效果的控制字符(请参阅Bell character ),例如播放哔哔声。

此外,strlen没有做您认为应该做的事情,因为加密的字符串不是以空字符结尾的,而是在其他字节中包含零,并且与以空字符结尾的字符串不同,它们没有特殊含义。您需要将字符串的长度存储在其他地方。

于 2012-10-12T11:18:32.337 回答
0

很简单,您将二进制输出(任何字节值)直接视为可打印文本。代码点低于 32(十六进制 20)的任何字符都不是。例如,BELL 的 ASCII 值(查找)可能对您有意义。以十六进制打印结果字节,你应该没问题。

于 2012-10-12T11:19:51.650 回答
0

我想补充一点,一般来说,如果可以的话,最好在加密后清除任何保存明文/未加密消息的内存。这不是好的编码实践,而是好的密码学实践。

这可以通过以下方式完成: memset(buffer, 0, length_of_buffer);

不用担心,编译器不会优化它。实际上,判断您是否会再次使用该区域还不够聪明。

于 2012-10-12T11:39:18.030 回答