Encrypt/ Decrypt - Libsodium 中的密钥认证加密(初学者)
Encrypt/ Decrypt - Secret-key authenticated encryption in Libsodium (beginner)
我正在按照此处的示例尝试加密和解密一个简单的字符串 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 有很好的文档记录并且很容易理解,尽管有时 cryto 主题可能有点困难,这是一个不错的选择。
我已对您的代码添加了注释以阐明其工作原理。我还添加了转储功能以简化代码理解。
#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
我正在按照此处的示例尝试加密和解密一个简单的字符串 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 有很好的文档记录并且很容易理解,尽管有时 cryto 主题可能有点困难,这是一个不错的选择。
我已对您的代码添加了注释以阐明其工作原理。我还添加了转储功能以简化代码理解。
#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