简体   繁体   English

Libgcrypt中的AES CCM加密和解密

[英]AES CCM Encryption and Decryption in Libgcrypt

I have a problem encrypting/decrypting a simple 16 byte message in Libgcrypt while using CCM mode of operation and AES algorithm. 在使用CCM操作模式和AES算法时,我在Libgcrypt中加密/解密一个简单的16字节消息时遇到问题。 In the documentation of Libgcrypt I cannot find which parameters to set for CCM (should I set IV or counter?). 在Libgcrypt的文档中,我无法找到为CCM设置的参数(我应该设置IV还是计数器?)。

I am stuck with the following code: 我坚持使用以下代码:

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);

How do I perform simple encryption/decryption using AES128 and CCM in Libgcrypt? 如何在Libgcrypt中使用AES128和CCM执行简单的加密/解密?

Example

The example is without additional non-encrypted data, therefore param[1] of gcry_cipher_ctl setting the GCRYCTL_SET_CCM_LENGTHS is 0. But it could be easily adjusted if required. 该示例没有附加的非加密数据,因此设置GCRYCTL_SET_CCM_LENGTHS的gcry_cipher_ctl的参数[1]为0.但是如果需要,可以很容易地调整它。

The functionality is divided into three parts: 功能分为三个部分:

  • prepare (set the key, the nonce (IV), and the CCM lengths) 准备(设置密钥,nonce(IV)和CCM长度)
  • encrypt function 加密功能
  • decrypt function 解密功能

If you run it, it will output the following text to the console: 如果您运行它,它将输出以下文本到控制台:

decrypted result: 'VNiJkPzAWPFm1234'

Code

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM