在 C 中将 Int 附加到 char *
Posted
技术标签:
【中文标题】在 C 中将 Int 附加到 char *【英文标题】:Appending an Int to a char * in C 【发布时间】:2013-08-30 09:20:07 【问题描述】:所以我希望将密文的长度附加到我存储密码的 char 数组的末尾。我不是 C 的本地人,下面是我设计的测试 sn-p我认为有效。
...
int cipherTextLength = 0;
unsigned char *cipherText = NULL;
...
EVP_EncryptFinal_ex(&encryptCtx, cipherText + cipherTextLength, &finalBlockLength);
cipherTextLength += finalBlockLength;
EVP_CIPHER_CTX_cleanup(&encryptCtx);
// Append the length of the cipher text onto the end of the cipher text
// Note, the length stored will never be anywhere near 4294967295
char cipherLengthChar[1];
sprintf(cipherLengthChar, "%d", cipherTextLength);
strcat(cipherText, cipherLengthChar);
printf("ENC - cipherTextLength: %d\n", cipherTextLength);
...
问题是我认为在处理二进制数据时使用strcat
不会有问题。谁能提出更好的方法来做到这一点?
谢谢!
编辑
好的,所以我将添加一些上下文,说明我为什么要附加长度。在我的encrypt
函数中,函数EVP_EncryptUpdate
需要加密plainText
的长度。因为这更容易获得,所以这部分不是问题。然而,类似地,在我的decrypt
函数中使用EVP_DecryptFinal_ex
需要解密ciperText
的长度,所以我需要将它存储在某个地方。
在我正在实现此功能的应用程序中,我所做的只是将一些糟糕的哈希更改为正确的加密。为了增加麻烦,应用程序的方式是我首先需要解密从 XML 读取的信息,对其进行处理,然后对其进行加密并再次将其重写为 XML,因此我需要以某种方式将此密码长度存储在密码中。我也没有重新设计这个的余地。
【问题讨论】:
【参考方案1】:与您现在所做的不同,将密文大小编码到密文本身之前的位置可能更聪明。一旦开始解密,最后找到大小就不是很有用了。您需要知道结束才能找到结束的大小,这不是很有帮助。
此外,密文是二进制的,因此您无需将任何内容转换为字符串。您想将其转换为固定数量的字节(否则您不知道 size 的大小 :P )。因此,创建一个更大的缓冲区(比密文所需的多 4 个字节),并开始加密以向前偏移 4 个。然后将密文的大小复制到缓冲区的开头。
如果您不知道如何对整数进行编码,请查看 - 例如 - this question/ answer。请注意,对于2^32
的最大密文大小,这只会编码 32 位,大约 4 GiB。此外,该链接指向使用 Big Endian 编码。您应该使用 Big Endian(首选加密代码)或 Little Endian 编码 - 但不要将两者混合使用。
密文和编码大小都不能用作字符串。如果需要字符串,我的建议是对缓冲区进行 base 64 编码,直到密文结尾。
【讨论】:
是的,在阅读了其他 cmets 之后,我决定添加长度。我喜欢偏移缓冲区的想法,这样我就知道密文将从哪里开始。非常感谢!【参考方案2】:我希望您有足够大的数组用于 cipherText 和 cipheLegthChar 来存储所需的文本。因此,而不是
unsigned char *cipherText = NULL;
你可以拥有
unsigned char cipherText[MAX_TEXT];
类似
cipherLenghthChar[MAX_INT];
或者您可以让它们动态分配。
其中 MAX_TEXT 和 MAX_INT 存储文本和整数的最大缓冲区大小。同样在第一次调用 EVP_EncryptFinal_ex NULL 后终止 cipherText 以便您 strcat 工作。
【讨论】:
【参考方案3】:问题是我认为在处理二进制数据时使用 strcat 不会有问题。
正确!不过,这不是您唯一的问题:
// Note, the length stored will never be anywhere near 4294967295
char cipherLengthChar[1];
sprintf(cipherLengthChar, "%d", cipherTextLength);
即使cipherTextLength
在这里是 0,你已经超出了界限,因为sprintf
将添加一个空终止符,总共有两个字符 - 但cipherLengthChar
只能容纳一个字符。
如果你考虑,例如4294967295,作为一个字符串,即 10 个字符 + '\0'
= 11 个字符。
看起来finalBlockLength
是放入cipherText
的数据的长度。但是,EVP_EncryptFinal_ex()
调用可能会以某种方式失败,或者至少不会做你想做的事,因为cipherText == NULL
。然后将 0 添加到该值(== 0 aka。仍然为 NULL)并将其作为参数提交。要么你需要一个指向那里的指针(如果EVP_EncryptFinal_ex
将为你分配空间),或者你必须确保cipherText
有足够的空间开始。
关于将文本(或其他)添加到末尾,您可以直接使用 sprintf:
sprintf(cipherText + finalBlockLength, "%d", cipherTextLength);
假设cipherText
是非NULL 并且有足够的extra 空间(参见前几段)。
但是,我很怀疑这样做以后会有用,但由于我没有任何进一步的背景,我不能说更多。
【讨论】:
以上是关于在 C 中将 Int 附加到 char *的主要内容,如果未能解决你的问题,请参考以下文章