gpt4 book ai didi

c - Libgcrypt 中的 AES CCM 加密和解密

转载 作者:行者123 更新时间:2023-11-30 16:16:44 50 4
gpt4 key购买 nike

在使用 CCM 操作模式和 AES 算法时,我在 Libgcrypt 中加密/解密简单的 16 字节消息时遇到问题。在Libgcrypt的文档中我找不到为CCM设置哪些参数(我应该设置IV还是计数器?)。

我被以下代码困住了:

gcry_error_t     err;
gcry_cipher_hd_t hd;

char * key = "1234567890123456";
char * plainText = "VNiJkPzAWPFm1234";
size_t messageSize = strlen(plainText);
char * cipherText = malloc(messageSize);
char * recoveredText = malloc(messageSize);

err = gcry_cipher_open(
&hd,
GCRY_CIPHER_AES128,
GCRY_CIPHER_MODE_CCM,
0);

err = gcry_cipher_setkey(hd, key, 16);

/* What to do here? */

err = gcry_cipher_encrypt(
hd,
cipherText,
messageSize,
plainText,
messageSize);

err = gcry_cipher_decrypt(
hd,
recoveredText,
messageSize,
cipherText,
messageSize);

如何在 Libgcrypt 中使用 AES128 和 CCM 执行简单的加密/解密?

最佳答案

示例

该示例没有额外的非加密数据,因此 gcry_cipher_ctl 的 param[1] 设置 GCRYCTL_SET_CCM_LENGTHS 为 0。但如果需要,可以轻松调整。

该功能分为三个部分:

  • 准备(设置 key 、随机数 (IV) 和 CCM 长度)
  • 加密功能
  • 解密函数

如果运行它,它将向控制台输出以下文本:

decrypted result: 'VNiJkPzAWPFm1234'

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gcrypt.h>

void error(const char *what, gcry_error_t err) {
fprintf(stderr, "%s failed: %s\n", what, gcry_strerror(err));
exit(1);
}

typedef struct {
const void *key;
const void *nonce;
size_t messageSize;
int authTagLength;
} Config;

void prepare(Config config, gcry_cipher_hd_t *hd) {
gcry_error_t err = gcry_cipher_open(hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CCM, 0);
if (err) { error("gcry_cipher_open", err); }

err = gcry_cipher_setkey(*hd, config.key, strlen(config.key));
if (err) { error("gcry_cipher_setkey", err); }

err = gcry_cipher_setiv(*hd, config.nonce, strlen(config.nonce));
if (err) { error("gcry_cipher_setiv", err); }

uint64_t params[3];
params[0] = config.messageSize;
params[1] = 0;
params[2] = config.authTagLength;
err = gcry_cipher_ctl(*hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(params));
if (err) { error("gcry_cipher_ctl", err); }
}

void *encrypt(Config config, const void *plainText, void **tag) {
gcry_cipher_hd_t hdEncrypt;
prepare(config, &hdEncrypt);

void *cipherText = malloc(config.messageSize);
gcry_error_t err = gcry_cipher_encrypt(hdEncrypt, cipherText, config.messageSize, plainText, config.messageSize);
if (err) { error("gcry_cipher_encrypt", err); }

*tag = malloc(config.authTagLength);
err = gcry_cipher_gettag(hdEncrypt, *tag, config.authTagLength);
if (err) { error("gcry_cipher_encrypt", err); }

gcry_cipher_close(hdEncrypt);

return cipherText;
}

void *decrypt(Config config, void *cipherText, void *tag) {
gcry_cipher_hd_t hdDecrypt;
prepare(config, &hdDecrypt);

void *recoveredText = malloc(config.messageSize);
gcry_error_t err = gcry_cipher_decrypt(hdDecrypt, recoveredText, config.messageSize, cipherText, config.messageSize);
if (err) { error("gcry_cipher_decrypt", err); }

err = gcry_cipher_checktag(hdDecrypt, tag, config.authTagLength);
if (gpg_err_code (err) == GPG_ERR_CHECKSUM) {
error("Authentication", err);
}

gcry_cipher_close(hdDecrypt);
return recoveredText;
}

int main() {
const char *plainText = "VNiJkPzAWPFm1234";

Config config;
config.key = "1234567890123456";
config.nonce = "0123456789012";
config.messageSize = strlen(plainText) + 1;
config.authTagLength = 10;

void *tag;
void *cipherText = encrypt(config, plainText, &tag);

char *recoveredText = decrypt(config, cipherText, tag);
printf("decrypted result: '%s'\n", recoveredText);

free(tag);
free(cipherText);
free(recoveredText);

return 0;
}

关于c - Libgcrypt 中的 AES CCM 加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56509552/

50 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com