libsodium crypto_box_seal_open 失败
libsodium crypto_box_seal_open failing
我正在使用以下函数使用 libsodium 创建一个密封盒:
void encrypt_message(char *msg, char *enc_msg, int db_id)
{
unsigned char pk[crypto_box_PUBLICKEYBYTES] = { '[=11=]' };
char key[BUFLEN] = { '[=11=]' };
db_man_get_contacts_public_key(db_id, key);
sodium_hex2bin(pk, crypto_box_publickeybytes(), key, sizeof(key),
NULL, NULL, NULL);
crypto_box_seal(enc_msg, msg, sizeof(msg), pk);
}
之后,我将二进制加密消息转换为十六进制,以便存储在磁盘上,利用以下 libsodium 函数
sodium_bin2hex(hex_cipher_text, sizeof(hex_cipher_text),
cipher_text, sizeof(cipher_text));
然后将hex_cipher_text存储在SQLite3数据库中。当我检索要解密的消息时,对 libsodium 的调用失败,错误代码为 1。我的解密函数如下:
void decrypt_message(message *msg)
{
unsigned char pk[crypto_box_SECRETKEYBYTES] = { '[=13=]' };
unsigned char pubkey[crypto_box_PUBLICKEYBYTES] = { '[=13=]' };
char key[BUFLEN] = { '[=13=]' };
unsigned char tmp[BUFLEN] = { '[=13=]' };
int dbg = 0;
db_man_get_my_private_key(key);
sodium_hex2bin(pk, crypto_box_secretkeybytes(), key, sizeof(key), NULL, NULL, NULL);
memset(key, '[=13=]', BUFLEN);
db_man_get_my_public_key(key);
sodium_hex2bin(pubkey, crypto_box_publickeybytes(), key, sizeof(key),
NULL, NULL, NULL);
sodium_hex2bin(tmp, sizeof(tmp), msg->enc_body, sizeof(msg- >enc_body),
NULL, NULL, NULL);
if ((dbg = crypto_box_seal_open(msg->dec_body, tmp, sizeof(tmp), pubkey, pk) != 0))
{
fprintf(stderr, "Decryption failed!\nError code: %d\n\n", dbg);
}
}
如有任何建议,我们将不胜感激。
已更新
根据Frank Denis和DamV的建议,我修改了之前的加密和解密函数如下;请注意从 sizeof() 函数调用到适当的 strlen() 函数调用的变化。
void encrypt_message(char *msg, char *enc_msg, int db_id)
{
unsigned char pk[crypto_box_PUBLICKEYBYTES] = { '[=14=]' };
char key[BUFLEN] = { '[=14=]' };
db_man_get_contacts_public_key(db_id, key);
sodium_hex2bin(pk, crypto_box_publickeybytes(), key, strlen(key),
NULL, NULL, NULL);
crypto_box_seal(enc_msg, msg, USR_MSG_MAX_LENGTH, pk);
}
void decrypt_message(message *msg)
{
unsigned char pk[crypto_box_SECRETKEYBYTES] = { '[=14=]' };
unsigned char pubkey[crypto_box_PUBLICKEYBYTES] = { '[=14=]' };
char key[BUFLEN] = { '[=14=]' };
unsigned char tmp[BUFLEN] = { '[=14=]' };
int dbg = 0;
db_man_get_my_private_key(key);
sodium_hex2bin(pk, crypto_box_secretkeybytes(), key, strlen(key),
NULL, NULL, NULL);
memset(key, '[=14=]', BUFLEN);
db_man_get_my_public_key(key);
sodium_hex2bin(pubkey, crypto_box_publickeybytes(), key,
strlen(key), NULL, NULL, NULL);
sodium_hex2bin(tmp, sizeof(tmp), msg->enc_body, strlen(msg->enc_body),
NULL, NULL, NULL);
if ((dbg = crypto_box_seal_open(msg->dec_body, tmp,
USR_MSG_MAX_LENGTH + crypto_box_SEALBYTES, pubkey, pk) != 0))
{
fprintf(stderr, "Decryption failed!\nError code: %d\n\n", dbg);
}
}
When I retrieve the message for decryption, the call to libsodium fails with an error code of 1
你是认真的returns-1,对吧?
我想知道问题是否与包含二进制值的数组的大小有关。我的意思是,如果以十六进制形式存储的数据的大小小于您分配用于存储它的 buf,您将丢失 buf 的哪一部分已实际写入的信息。
我特别关心 enc_body -> tmp。如果二进制数据的大小小于 BUFLEN,您将给 crypto_box_seal_open 一个比您想要提供的缓冲区大小更大的缓冲区。它会导致解密问题,不是吗?
实际上我认为你必须在调用 hex2bin 后恢复数据的大小(它可能会输出它),然后将它传递给 crypto_box_seal_open 而不是 sizeof(tmp) (又名 BUFLEN)。
sizeof <pointer>
returns 一个常量,指针本身的大小。
在您的代码中 sizeof(msg)
将始终 return 4 或 8,无论消息大小如何。
sizeof(msg->enc_body)
可能也不会按照您的要求去做。
如果您是 C 语言的新手,我建议您忘记 sizeof
关键字。
您很少需要它,它是该语言新手编写的应用程序中出现混乱、错误和漏洞的主要原因。
您唯一需要记住的是 sizeof (<type>)
或 sizeof value
始终 return 是一个常数。
我正在使用以下函数使用 libsodium 创建一个密封盒:
void encrypt_message(char *msg, char *enc_msg, int db_id)
{
unsigned char pk[crypto_box_PUBLICKEYBYTES] = { '[=11=]' };
char key[BUFLEN] = { '[=11=]' };
db_man_get_contacts_public_key(db_id, key);
sodium_hex2bin(pk, crypto_box_publickeybytes(), key, sizeof(key),
NULL, NULL, NULL);
crypto_box_seal(enc_msg, msg, sizeof(msg), pk);
}
之后,我将二进制加密消息转换为十六进制,以便存储在磁盘上,利用以下 libsodium 函数
sodium_bin2hex(hex_cipher_text, sizeof(hex_cipher_text),
cipher_text, sizeof(cipher_text));
然后将hex_cipher_text存储在SQLite3数据库中。当我检索要解密的消息时,对 libsodium 的调用失败,错误代码为 1。我的解密函数如下:
void decrypt_message(message *msg)
{
unsigned char pk[crypto_box_SECRETKEYBYTES] = { '[=13=]' };
unsigned char pubkey[crypto_box_PUBLICKEYBYTES] = { '[=13=]' };
char key[BUFLEN] = { '[=13=]' };
unsigned char tmp[BUFLEN] = { '[=13=]' };
int dbg = 0;
db_man_get_my_private_key(key);
sodium_hex2bin(pk, crypto_box_secretkeybytes(), key, sizeof(key), NULL, NULL, NULL);
memset(key, '[=13=]', BUFLEN);
db_man_get_my_public_key(key);
sodium_hex2bin(pubkey, crypto_box_publickeybytes(), key, sizeof(key),
NULL, NULL, NULL);
sodium_hex2bin(tmp, sizeof(tmp), msg->enc_body, sizeof(msg- >enc_body),
NULL, NULL, NULL);
if ((dbg = crypto_box_seal_open(msg->dec_body, tmp, sizeof(tmp), pubkey, pk) != 0))
{
fprintf(stderr, "Decryption failed!\nError code: %d\n\n", dbg);
}
}
如有任何建议,我们将不胜感激。
已更新
根据Frank Denis和DamV的建议,我修改了之前的加密和解密函数如下;请注意从 sizeof() 函数调用到适当的 strlen() 函数调用的变化。
void encrypt_message(char *msg, char *enc_msg, int db_id)
{
unsigned char pk[crypto_box_PUBLICKEYBYTES] = { '[=14=]' };
char key[BUFLEN] = { '[=14=]' };
db_man_get_contacts_public_key(db_id, key);
sodium_hex2bin(pk, crypto_box_publickeybytes(), key, strlen(key),
NULL, NULL, NULL);
crypto_box_seal(enc_msg, msg, USR_MSG_MAX_LENGTH, pk);
}
void decrypt_message(message *msg)
{
unsigned char pk[crypto_box_SECRETKEYBYTES] = { '[=14=]' };
unsigned char pubkey[crypto_box_PUBLICKEYBYTES] = { '[=14=]' };
char key[BUFLEN] = { '[=14=]' };
unsigned char tmp[BUFLEN] = { '[=14=]' };
int dbg = 0;
db_man_get_my_private_key(key);
sodium_hex2bin(pk, crypto_box_secretkeybytes(), key, strlen(key),
NULL, NULL, NULL);
memset(key, '[=14=]', BUFLEN);
db_man_get_my_public_key(key);
sodium_hex2bin(pubkey, crypto_box_publickeybytes(), key,
strlen(key), NULL, NULL, NULL);
sodium_hex2bin(tmp, sizeof(tmp), msg->enc_body, strlen(msg->enc_body),
NULL, NULL, NULL);
if ((dbg = crypto_box_seal_open(msg->dec_body, tmp,
USR_MSG_MAX_LENGTH + crypto_box_SEALBYTES, pubkey, pk) != 0))
{
fprintf(stderr, "Decryption failed!\nError code: %d\n\n", dbg);
}
}
When I retrieve the message for decryption, the call to libsodium fails with an error code of 1
你是认真的returns-1,对吧?
我想知道问题是否与包含二进制值的数组的大小有关。我的意思是,如果以十六进制形式存储的数据的大小小于您分配用于存储它的 buf,您将丢失 buf 的哪一部分已实际写入的信息。
我特别关心 enc_body -> tmp。如果二进制数据的大小小于 BUFLEN,您将给 crypto_box_seal_open 一个比您想要提供的缓冲区大小更大的缓冲区。它会导致解密问题,不是吗?
实际上我认为你必须在调用 hex2bin 后恢复数据的大小(它可能会输出它),然后将它传递给 crypto_box_seal_open 而不是 sizeof(tmp) (又名 BUFLEN)。
sizeof <pointer>
returns 一个常量,指针本身的大小。
在您的代码中 sizeof(msg)
将始终 return 4 或 8,无论消息大小如何。
sizeof(msg->enc_body)
可能也不会按照您的要求去做。
如果您是 C 语言的新手,我建议您忘记 sizeof
关键字。
您很少需要它,它是该语言新手编写的应用程序中出现混乱、错误和漏洞的主要原因。
您唯一需要记住的是 sizeof (<type>)
或 sizeof value
始终 return 是一个常数。