在c中制作一长串加密的子串

Posted

技术标签:

【中文标题】在c中制作一长串加密的子串【英文标题】:Make a long string of encrypted substrings in c 【发布时间】:2012-10-03 04:16:41 【问题描述】:

我正在尝试创建一个由加密子字符串生成的长字符串。对于加密,我使用AES128libmcrypt。代码正在运行,但我得到的输出比我应该得到的更短,并且会发出哔哔声。我想这是因为我使用的是strlen,但我不知道如何避免这种情况。我将非常感谢一些建议。这是我的代码:

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;

【问题讨论】:

亲爱的用户,别忘了实际接受答案。 【参考方案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。

【讨论】:

谢谢大家的回答。我明白,问题在于加密的消息可能包含零,但我怎样才能将这些零保留在字符串中。我实际上稍后会使用字符串在图片中创建随机线,所以我需要具有特定长度的特定字符串。我希望我能够清楚地表达我的自我。谢谢! 没有办法在我的长字符串中保留零吗?正如我所写的,我想稍后使用它并对其进行加密。谢谢!【参考方案2】:

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

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

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

【讨论】:

字节不会超过 0..255,它们只是字节。这取决于character-encoding 的打印方式。在大多数情况下,最低有效 7 位形成一个 ASCII 编码字符,这就是定义控制字符的地方(并且不再经常使用这些字符)。【参考方案3】:

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

【讨论】:

【参考方案4】:

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

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

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

【讨论】:

以上是关于在c中制作一长串加密的子串的主要内容,如果未能解决你的问题,请参考以下文章

java:一长串条件,怎么办? [关闭]

非对称加密:谁能花费那些比特币?

在 Powershell 中过滤一长串列表

如何在 VueJS 中将一长串“手表”转换为功能方式?

题目1021:统计字符------------------------主要注意输入的方法,如何让一长串的字符都接收到字符串中

存储一长串值的最佳方法