C / C ++中以null结尾的字符串的长度

时间:2015-02-05 17:03:57

标签: c++ c openssl

我使用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,但据我所知的方法都没有给出正确的输出。

3 个答案:

答案 0 :(得分:4)

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

现在用AES加密字符串后(比如字符串的长度是32字节) - 你不能再使用strlen来获得结果的长度了,因为结果,不再是字符串它是一些表示加密结果的字节数组。实际上你不需要获得长度,它将与明文大小相同 - 我们在案例中说的是32字节。

所以我认为你不再有计算长度的问题 - 现在如果对方应该知道密文的长度,你可以在数据包中预先发送长度(在我们的例子中是32)。另一方现在应重建纯文本(如果使用了填充字节,还应删除填充字节)。

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

关于评论,我将尝试简要介绍这一过程的进展情况。假设您有字符串char * str = "hello" - 这是5个字节,您需要加密它。就像我说过你不能直接对它进行加密一样,你需要将它填充为16的倍数。为此你可以使用PKCS7填充(它类似于details但是用于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方法似乎可以解决这个问题。

答案 1 :(得分:1)

如果数组中的有效数据没有终止,那么就无法通过查看数组来判断它的长度。

如果envelope_seal告诉你长度,那么使用它,将它传递到需要长度的地方。

答案 2 :(得分:1)

AES是一种分组密码。因此,ciphertext的长度将是plaintext模块大小的长度,向上舍入到最近的块大小。