在c中制作一长串加密的子串
Posted
技术标签:
【中文标题】在c中制作一长串加密的子串【英文标题】:Make a long string of encrypted substrings in c 【发布时间】:2012-10-03 04:16:41 【问题描述】:我正在尝试创建一个由加密子字符串生成的长字符串。对于加密,我使用AES128
和libmcrypt
。代码正在运行,但我得到的输出比我应该得到的更短,并且会发出哔哔声。我想这是因为我使用的是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中制作一长串加密的子串的主要内容,如果未能解决你的问题,请参考以下文章
题目1021:统计字符------------------------主要注意输入的方法,如何让一长串的字符都接收到字符串中