Strange behavior of crypto_box_easy and crypto_box_open_easy. Decrypt without private key?

随声附和 提交于 2019-12-23 19:20:42

问题


I have tested Public-key-cryptography by libsodium and came across a strange behavior. The encrypted message is decrypted without the private key.

Example from official site libsodium

#include "sodium.h"

#define MESSAGE         "test"
#define MESSAGE_LEN     4
#define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)

static bool TestSodium()
{
    unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
    unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
    crypto_box_keypair(alice_publickey, alice_secretkey);

    unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
    unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
    crypto_box_keypair(bob_publickey, bob_secretkey);

    unsigned char nonce[crypto_box_NONCEBYTES];
    unsigned char ciphertext[CIPHERTEXT_LEN];
    randombytes_buf(nonce, sizeof nonce);

    // message alice -> bob
    if (crypto_box_easy(ciphertext, (const unsigned char*)MESSAGE, MESSAGE_LEN, nonce, bob_publickey, alice_secretkey) != 0)
    {
        return false;
    }

    unsigned char decrypted[MESSAGE_LEN + 1];
    decrypted[MESSAGE_LEN] = 0;

    // Original!
    //if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, alice_publickey, bob_secretkey) != 0)

    // Whis works without Bobs secret key!
    if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, bob_publickey, alice_secretkey) != 0)
    {
        return false;
    }

    if(strcmp((const char*)decrypted, MESSAGE) != 0) return false;

    return true;
}

Using public-key authenticated encryption, Alice can encrypt a confidential message specifically for Bob, using Bob's public key.

Using Alice's public key, Bob can verify that the encrypted message was actually created by Alice and was not tampered with, before eventually decrypting it.

Bob only needs Alice's public key, the nonce and the ciphertext.

And in order to send messages to Bob, Alice only needs Bobs's public key.

In original examle Bob decrypts message from Alice by own secret key and verifies it by Alice's public key. I made a mistake in code and message was properly decrypted without Bob's private key!

How it is possible? Where is my mistake? Thanks


回答1:


Yes it is possible

In libsodium, public-key authenticated encryption is done in three separate phases, in that order:

  1. Key exchange — Use an elliptic-curve Diffie-Hellman algorithm (X25519) to generate the shared secret keys from my private key and your public key.

    • This is the crypto_box_beforenm step.
  2. Encryption — Apply symmetric-key encryption (XSalsa20) to the plaintext message using a shared secret key generated in step 1.

  3. Authentication — Generate a MAC (Poly1305), again relying on the keys generated in the above steps.

    • These are the crypto_box_afternm steps, which are the same as crypto_secretbox_easy.

Using symmetric encryption in steps 2-3 means the same key must be computable by both Alice and Bob, i.e.

shared_key_computed_by_alice = crypto_box_beforenm(bob_pk, slice_sk)
shared_key_computed_by_bob = crypto_box_beforenm(alice_pk, bob_sk) 
assert(shared_key_computed_by_alice == shared_key_computed_by_bob)

Since we require both key pairs to generate the same shared secret key, it is not hard to see that both pairs can also decrypt the same message.

And this is fine

Note that in your implementation of the "wrong" decryption, you not only used Bob's public key, but also Alice's private key (which only Alice knows).

Since it is Alice that wants to send the encrypted message to Bob, this means Alice should already know the plain text message in the first place. So she can decrypt that message using her own private key is not a security problem.

The decryption routine would really fail if you used Bob's public key with another person (Eve)'s private key.

 

If you think Alice being able to decrypt her own message is a problem, you could force Alice to destroy her private key after the conversation 😛, so now only Bob can decrypt it (and no more messages can be sent from Alice).

In fact libsodium provides the sealed box API which does this (generate an ephemeral key-pair and destroys it right after encryption).



来源:https://stackoverflow.com/questions/39797321/strange-behavior-of-crypto-box-easy-and-crypto-box-open-easy-decrypt-without-pr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!