C/C++ 中空终止字符串的长度
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,但据我所知,none 方法给出了正确的输出。
如果数组中的有效数据没有终止,则无法通过查看数组来判断其长度。
如果 envelope_seal
告诉你长度,则使用它,将它传递到需要长度的地方。
AES 是分组密码。因此 ciphertext
的长度将是您的 plaintext
模块大小的长度,四舍五入到最接近的块大小。
AES 是分组密码。它的块大小为 16 字节——这意味着如果你想用它加密一些数据,数据的字节长度必须是 16 的倍数(如果不是,你可能需要使用填充,比如 PKCS7,更多 details).
现在用 AES 加密 string 之后(比如字符串的长度是 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 的工作方式,参见我的 link-PKCS7 是仅对 16 字节块长度类似),并获得 "hello".
最后,我看不出问题在哪里,当你从客户端发送到服务器时,你可以只对消息长度进行编码,例如数据包中的16,这样接收方就知道16字节代表密文。但正如我所说,使用这 16 个字节,接收器在解密后将能够确定只有前 5 个字节是原始文本(由于使用了填充 PKCS7)。所以除了16之外不需要发送任何东西;在 PKCS 填充方案的帮助下,您将能够分辨出只有前 5 个字节是纯文本。
ps。在与 OP 进行一些讨论后,填充似乎不是他的主要问题,因为使用的 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,但据我所知,none 方法给出了正确的输出。
如果数组中的有效数据没有终止,则无法通过查看数组来判断其长度。
如果 envelope_seal
告诉你长度,则使用它,将它传递到需要长度的地方。
AES 是分组密码。因此 ciphertext
的长度将是您的 plaintext
模块大小的长度,四舍五入到最接近的块大小。
AES 是分组密码。它的块大小为 16 字节——这意味着如果你想用它加密一些数据,数据的字节长度必须是 16 的倍数(如果不是,你可能需要使用填充,比如 PKCS7,更多 details).
现在用 AES 加密 string 之后(比如字符串的长度是 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 的工作方式,参见我的 link-PKCS7 是仅对 16 字节块长度类似),并获得 "hello".
最后,我看不出问题在哪里,当你从客户端发送到服务器时,你可以只对消息长度进行编码,例如数据包中的16,这样接收方就知道16字节代表密文。但正如我所说,使用这 16 个字节,接收器在解密后将能够确定只有前 5 个字节是原始文本(由于使用了填充 PKCS7)。所以除了16之外不需要发送任何东西;在 PKCS 填充方案的帮助下,您将能够分辨出只有前 5 个字节是纯文本。
ps。在与 OP 进行一些讨论后,填充似乎不是他的主要问题,因为使用的 openssl 方法似乎可以解决这个问题。