C / C ++中以null结尾的字符串的长度(Length of null terminated string in C/C++)

编程入门 行业动态 更新时间:2024-10-28 04:17:32
C / C ++中以null结尾的字符串的长度(Length of null terminated string in C/C++)

我使用openssl来加密字符串,我得到空字符串结尾。 我现在已经加密了字符串,我想通过使用base64编码的网络发送它。 我只需要发送加密数据,如何在解密之前计算另一侧字符串的长度?

unsigned char *plaintext = (unsigned char*) "The quick brown fox jumps sover thes lazy dog"; unsigned char ciphertext[256] = {}; // After using openssl envelope_seal(), with EVP_aes_128_cbc() strlen((const char*)ciphertext) // length is different each time due to null terminated binary string sizeof(ciphertext) // lenght is equal to 256 int envelope_seal( ) // gives me the length of that string as 48.

请帮助我计算ciphertext长度为48,但我所知的方法都没有给我正确的输出。

I am using openssl to encrypt the string and i get null terminated string. I have now encrypted string and I want to send it over network with base64 encoding. I just need to send the encrypted data, how can I calculate the length of the string on the other side before decryption?

unsigned char *plaintext = (unsigned char*) "The quick brown fox jumps sover thes lazy dog"; unsigned char ciphertext[256] = {}; // After using openssl envelope_seal(), with EVP_aes_128_cbc() strlen((const char*)ciphertext) // length is different each time due to null terminated binary string sizeof(ciphertext) // lenght is equal to 256 int envelope_seal( ) // gives me the length of that string as 48.

Kindly help me to calculate the length of the ciphertext which is 48 but none of the method in my knowledge gives me the correct output.

最满意答案

AES是分组密码。 它的块大小为16字节 - 这意味着如果你想用它加密一些数据,数据的长度必须是16的倍数(如果不是,你可能需要使用填充,比如说PKCS7,更多细节 ) 。

现在用AES加密字符串 (比如说字符串的长度是32字节)之后 - 你不能再使用strlen来获得结果的长度,因为结果不再字符串了,它是一些字节数组加密的结果。 实际上,无论如何你都不需要知道长度,它将和明文一样大小 - 我们在这里说的是32个字节。

所以我认为你没有计算长度的问题了 - 现在如果对方应该知道密文的长度,你可以提前在包中发送长度(在我们的例子中是32)。 另一方应该现在重建纯文本(并且如果使用了一个,也会删除填充字节)。

注意:执行加密并获得密文后,您可以对其应用base64编码并将其发送,但您也可以发送代表密文的字节数组。

关于评论,我将尝试简要地强调这个过程的过程。 假设你有字符串char * str = "hello" - 这是5个字节,你需要加密它。 就像我说的,你不能直接加密它,你需要填充它以使16的倍数。为此,你可以使用PKCS7填充(它类似于PKCS5,但是对于16字节块)。 现在,当你应用填充,例如, char * paddedText = PKCS7(str) ,您将以16字节的字节数组结束。

现在,没有更多的问题。 你可以加密这16个字节的明文。 结果也将是16个字节的密文。

现在,如果你想解密这16字节的密文,你可以直接解密它(因为它是16的倍数)。 现在,由于PKCS7填充的工作方式,您可以轻松地从结果中得知只有前5个字节是原始字符串,并且您将删除11个冗余字节(PKCS5的工作方式,请参阅我的链接-PKCS7中的内容与16字节块长度),并获得“hello”。

最后,我不知道问题出在哪里,当你从客户端发送到服务器时,你可以对消息长度进行编码,例如,在数据包中包含16个字符,这样接收者就知道16个字节代表密文。 但是,正如我所说的,使用这16个字节,解密后的接收器将能够确定只有前5个字节是原始文本(由于使用了填充PKCS7)。 所以不需要发送任何东西,除了16; 在PKCS填充方案的帮助下,您将能够知道只有前5个字节是纯文本。

PS。 在与OP进行了一些讨论之后,似乎填充并不是他的主要问题,因为使用的openssl方法似乎处理这个问题。

AES is a block cipher. It has block size of 16 bytes - which means if you want to encrypt some data with it the length of the data in bytes must be multiple of 16 (if it is not you might need to use padding such as say PKCS7, more details).

Now after you encrypt a string with AES (say length of string is 32 bytes) - you can't use strlen anymore to get the length of the result, because the result, isn't a string anymore it is some byte array which represents the results of encryption. Actually you don't need to get the length anyway, it will be same size as plaintext - 32 bytes as we said in our case.

So I think you don't have issues with calculating length anymore - now if the other side should know length of the ciphertext you can send the length (say 32 in our case) in advance in packet. The other side should reconstruct the plain text now (and also remove padding bytes if one was used).

note: After you performed encryption and have the ciphertext you can apply base64 encoding to it and send it over, but you could as well send the byte array representing the ciphertext too.

In regard to comments, I will try to briefly highlight how this process goes. Say you have string char * str = "hello" - which is 5 bytes and you need to encrypt it. Like I said you can't encrypt it directly, you need to pad it to make multiple of 16. For this you can use PKCS7 padding (it is similar to PKCS5 but is for 16 bytes blocks). Now when you apply padding e.g., char * paddedText = PKCS7(str), you will end up with byte array which is 16 bytes.

Now, there is no more problem. You can encrypt this 16 bytes of plaintext. Result will also be 16 bytes cipher text.

Now if you want to decrypt this 16 bytes of cipher text, you can decrypt it directly (because it is multiple of 16). Now, due to the way PKCS7 padding works you will easily be able to tell from the result that only first 5 bytes were original string and you will remove 11 redundant bytes (how PKCS5 works, see in my link-PKCS7 is similar just for 16 byte block lengths), and obtain "hello".

Finally, I don't see where is the problem, when you send from client to server, you can just encode message length, e.g., 16 in packet, so that receiver knows 16 bytes represent cipher text. But again as I said, using this 16 bytes, the receiver, after decrypting will be able to determine that only first 5 bytes were original text (due to used padding PKCS7). So there is no need to send anything except 16; with help of PKCS padding scheme you will be able to tell that only first 5 bytes were plain text.

ps. After some discussions with OP it seems padding was not his main issue, because openssl method that was used seems to take care of that.

更多推荐

本文发布于:2023-07-24 13:22:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1246283.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字符串   中以   结尾   长度   null

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!