简体   繁体   English

在C中将Int附加到char *

[英]Appending an Int to a char * in C

So I am looking to append the length of a cipher text onto the end of the char array that I am storing the cipher in. I am not a native to C and below is a test snippet of what I have devised that I think works. 因此,我希望将密码文本的长度附加到要存储密码的char数组的末尾。我不是C语言的本机,下面是我认为可行的测试摘要。

...
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);
...

The problem is I don't think using strcat when dealing with binary data is going to be trouble free. 问题是我不认为在处理二进制数据时使用strcat不会带来麻烦。 Could anyone suggest a better way to do this? 有人可以建议一种更好的方法吗?

Thanks! 谢谢!

EDIT 编辑

Ok, so I'll add a little context as to why I was looking to append the length. 好的,所以我将添加一些关于为什么要添加长度的上下文。 In my encrypt function, the function EVP_EncryptUpdate requires the length of the plainText being encrypted. 在我的encrypt函数,该函数EVP_EncryptUpdate要求的长度plainText进行加密。 As this is much more easy to obtain, this part isn't a problem. 因为这更容易获得,所以这部分不是问题。 However, similarly, using EVP_DecryptFinal_ex in my decrypt function requires the length of the ciperText being decrypted, so I need to store it somewhere. 但是,类似地,在我的decrypt函数中使用EVP_DecryptFinal_ex需要decryptciperText的长度,因此我需要将其存储在某个地方。

In the application where I am implementing this, all I am doing is changing some poor hashing to proper encryption. 在我要实现此功能的应用程序中,我所要做的就是将一些不良的哈希更改为适当的加密。 To add further hassle, the way the application is I first need to decrypt information read in from XML, do something with it, then encrypt it and rewrite it to XML again, so I need to have this cipher length stored in the cipher somehow. 为了增加麻烦,我首先需要解密从XML读取的信息,对其进行处理,然后对其进行加密,然后再次将其重写为XML,因此,我需要将此密码长度以某种方式存储在密码中。 I also don't have scope to redesign this. 我也没有范围重新设计它。

I hope you are having enough big arrays both for cipherText and cipheLegthChar to store the required text. 我希望您有足够大的数组供cipherText和cipheLegthChar存储所需的文本。 Hence instead of 因此,代替

unsigned char *cipherText = NULL;

You can have 你可以有

unsigned char cipherText[MAX_TEXT];

similarly for 类似地

cipherLenghthChar[MAX_INT];

Or you can have them dynamically allocated. 或者,您可以动态分配它们。

where MAX_TEXT and MAX_INT max buffer size to store text and integer. 其中MAX_TEXT和MAX_INT最大缓冲区大小,用于存储文本和整数。 Also after first call of EVP_EncryptFinal_ex NULL terminate cipherText so that you strcat works. 同样,在第一次调用EVP_EncryptFinal_ex NULL之后,终止cipherText,以便您使用strcat。

The problem is I don't think using strcat when dealing with binary data is going to be trouble free. 问题是我不认为在处理二进制数据时使用strcat不会带来麻烦。

Correct! 正确! That's not your only problem though: 但是,这不是您唯一的问题:

// Note, the length stored will never be anywhere near 4294967295 
char cipherLengthChar[1];
sprintf(cipherLengthChar, "%d", cipherTextLength);

Even if cipherTextLength is 0 here, you've gone out of bounds, since sprintf will add a null terminator, making a total of two chars -- but cipherLengthChar only has room for one. 即使此处的cipherTextLength为0,您也已经超出范围,因为sprintf将添加一个空终止符,总共两个字符-但是cipherLengthChar仅可容纳一个字符。 If you consider, eg 4294967295, as a string, that's 10 chars + '\\0' = 11 chars. 如果考虑将4294967295作为字符串,则为10个字符+ '\\0' = 11个字符。

It would appear that finalBlockLength is the length of the data put into cipherText . 看来finalBlockLength是放入cipherText的数据的长度。 However, the EVP_EncryptFinal_ex() call will probably fail in one way or another, or at least not do what you want, since cipherText == NULL . 但是,由于cipherText == NULL ,因此EVP_EncryptFinal_ex()调用可能会以一种或另一种方式失败,或者至少不会执行您想要的操作。 You then add 0 to that (== 0 aka. still NULL) and submit it as a parameter. 然后,向其添加0(== 0,又称NULL)并将其作为参数提交。 Either you need a pointer to a pointer there (if EVP_EncryptFinal_ex is going to allocate space for you), or else you have to make sure there is enough room in cipherText to start with. 您要么需要一个指向那里的指针的指针(如果EVP_EncryptFinal_ex将为您分配空间),要么您必须确保cipherText有足够的空间开始。

With regard to tacking text (or whatever) onto the end, you can just use sprintf directly: 关于将文本(或其他内容)添加到末尾,您可以直接使用sprintf:

sprintf(cipherText + finalBlockLength, "%d", cipherTextLength);

Presuming that cipherText is non-NULL and has enough extra room in it (see first couple of paragraphs). 假定cipherText为非NULL并在其中有足够的额外空间(请参阅前几段)。

However, I'm very dubious that doing that will be useful later on, but since I don't have any further context, I can't say more. 但是,我非常怀疑这样做在以后会很有用,但是由于我没有更多的背景信息,所以我不能说更多。

Instead of what you are doing now, it may be smarter to encode the ciphertext size to a location before the ciphertext itself. 将密文的大小编码到密文本身之前的某个位置可能比现在更聪明。 Once you start decrypting, it is not very useful to find the size at the end. 一旦开始解密,在末尾查找大小并不是很有用。 You need to know the end to get the size to find the end, not very helpful. 您需要知道目标的大小才能找到目标,不是很有帮助。

Furthermore, the ciphertext is binary, so you don't need to convert anything to string. 此外,密文是二进制的,因此您无需将任何内容转换为字符串。 You would like to convert it to a fixed number of bytes (otherwise you don't know the size of the size :P ). 您想将其转换为固定数量的字节(否则您不知道size:P的大小)。 So create a bigger buffer (4 bytes more than you require for the ciphertext), and start encrypting to offset 4 forwards. 因此,创建一个更大的缓冲区(比密文需要的缓冲区多4个字节),然后开始加密以抵消4个转发。 Then copy the size of the ciphertext in at the start of the buffer. 然后在缓冲区的开始处复制密文的大小。

If you don't know how to encode an integer, take a look at - for instance - this question/ answer . 如果您不知道如何编码整数,请查看-例如- 这个问题/答案 Note, this will only encode 32 bits for a maximum size of the ciphertext of 2^32 , about 4 GiB. 请注意,对于密文的最大大小2^32 (大约4 GiB),这将仅编码32位。 Furthermore, the link pointed to use Big Endian encoding. 此外,该链接指向使用Big Endian编码。 You should use either Big Endian (preferred for crypto code) or Little Endian encoding - but don't mix the two. 您应该使用Big Endian(首选加密代码)或Little Endian编码-但不要将两者混用。

Neither the ciphertext nor the encoded size should be used as a character string. 密文和编码大小都不能用作字符串。 If you need a character string, my suggestion is to base 64 encode the buffer up to the end of the ciphertext. 如果您需要一个字符串,我的建议是对缓冲区进行base 64编码直到密文的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM