c - 加密/解密 - Libsodium 中的 key 验证加密(初学者)

标签 c encryption libsodium

我正在尝试按照此处的示例来加密和解密一个简单的字符串 Here

#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)

unsigned char key[crypto_secretbox_KEYBYTES];
unsigned char nonce[crypto_secretbox_NONCEBYTES];
unsigned char ciphertext[CIPHERTEXT_LEN];

crypto_secretbox_keygen(key);
randombytes_buf(nonce, sizeof nonce);
crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);

unsigned char decrypted[MESSAGE_LEN];
if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, 
key) != 0) {
    /* message forged! */
}

我的问题是:如何取回原文? 'test'在这种情况下? Libsodium似乎使用unsigned char*自始至终。所有 Libsodium 示例似乎都以 "Message forged!" 结尾。后续一个问题,如何将密文转换成可序列化的格式?

最佳答案

首先,libsodium 有完善的文档记录,并且很容易理解,尽管事实上 crypto 主题有时可能有点困难,所以是不错的选择。

我已在您的代码中添加了注释以阐明其工作原理。我还添加了转储功能以方便代码理解。

#include <stdlib.h>
#include <stdio.h>
#include <sodium.h>

#define MESSAGE ((const unsigned char *) "test")
#define MESSAGE_LEN 4
#define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN)

void dump_hex_buff(unsigned char buf[], unsigned int len)
{
    int i;
    for (i=0; i<len; i++) printf("%02X ", buf[i]);
    printf("\n");
}

int main(int argc, char *argv[])
{
    /* Variable declaration */
    unsigned char key[crypto_secretbox_KEYBYTES];
    unsigned char nonce[crypto_secretbox_NONCEBYTES];
    unsigned char ciphertext[CIPHERTEXT_LEN];
    unsigned char decrypted[MESSAGE_LEN];

    /* Generating a random key */
    crypto_secretbox_keygen(key);
    printf("secret key generated:\n");
    dump_hex_buff(key, crypto_secretbox_KEYBYTES);

    /* Using random bytes for a nonce buffer (a buffer used only once) */
    randombytes_buf(nonce, sizeof nonce);
    printf("nonce:\n");
    dump_hex_buff(nonce, sizeof nonce);

    /* Encrypt MESSAGE using key and nonce
       Encrypted message is stored in ciphertext buffer */
    crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key);
    printf("ciphertext:\n");
    dump_hex_buff(ciphertext, CIPHERTEXT_LEN);



    /* Decrypt ciphertext buffer using key and nounce
       Decrypted message is stored in decrypted buffer */
    if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) {
        /* message forged!, meaning decryption failed */

    } else {
        /* Successful decryption */
        printf("decrypted data (hex):\n");
        dump_hex_buff(decrypted, MESSAGE_LEN);
        printf("decrpyted data (ascii):%.4s\n", decrypted);
    }

    return 0;
}

当您说需要序列化解密数据时,您需要澄清您想要什么。该库使用标准 C 数组。

如果您使用的是 Linux,则可以使用以下方式编译代码:

gcc -o pgm main.c/usr/local/lib/libsodium.a

代码输出结果:

secret key generated:
87 28 B9 43 0E DA B5 37 CD 3A 67 A3 DB 4A 31 24 67 4E E3 81 AE 03 FB 81 B7 60 2E 1A F3 6A A6 F4 
nonce:
7B 11 84 24 55 24 98 7A 6B 0B 23 34 66 48 8F 1C C3 4E 20 3E 42 31 02 9B 
ciphertext:
00 BC C0 86 61 37 00 0D 90 76 46 C3 17 39 A5 00 E3 F8 A8 9D 
decrypted data (hex):
74 65 73 74 
decrpyted data (ascii):test

关于c - 加密/解密 - Libsodium 中的 key 验证加密(初学者),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51786187/

相关文章:

c++ - 如何在预处理时读取文件

c++ - Linux 上的 PThreads 和多核 CPU

谁能弄清楚为什么我的循环不能正常工作

java - 字符与字符串不兼容

c - 推荐的*最小*椭圆曲线库

java - 无法使用 "SecretBox"(C#) 打开 TweetNacl (Java) 生成的 "Libsodium-net"

c - inline 关键字导致 Clion 中的链接器错误

java - Android 中的 Base64 加密

Java JNI在Linux上加载libc.so时出现问题,尝试加载ASCII/usr/lib64/libc.so,发现它确实不是ELF文件

javascript - 我是否正确地散列密码?