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 DenisDamV的建议,我修改了之前的加密和解密函数如下;请注意从 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 是一个常数。