Libgcrypt中的AES-CCM加密和解密
在使用CCM操作模式和AES算法时,我在Libgcrypt中加密/解密简单的16字节消息时遇到问题。在Libgcrypt的文档中,我找不到要为CCM设置哪些参数(我应该设置IV还是计数器?) 我被以下代码困住了:Libgcrypt中的AES-CCM加密和解密,c,aes,libgcrypt,C,Aes,Libgcrypt,在使用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
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执行简单的加密/解密?示例
#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;
}
该示例没有额外的非加密数据,因此gcry_cipher_ctl的参数[1]设置GCRYCTL_SET_CCM_长度为0。但如果需要,它可以很容易地调整
该功能分为三个部分:
- 准备(设置键、当前值(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;
}
#包括
#包括
#包括
#包括
无效错误(const char*what,gcry\u error\t err){
fprintf(标准,“%s失败:%s\n”,什么,gcry_strerror(err));
出口(1);
}
类型定义结构{
const void*键;
const void*nonce;
大小信息大小;
int-authTagLength;
}配置;
无效准备(配置配置,gcry\u密码\u hd\u t*hd){
gcry\u error\u t err=gcry\u cipher\u open(hd,gcry\u cipher\u AES128,gcry\u cipher\u MODE\u CCM,0);
if(err){error(“gcry_cipher_open”,err);}
err=gcry\u cipher\u 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参数[3];
params[0]=config.messageSize;
参数[1]=0;
params[2]=config.authTagLength;
err=gcry_cipher_ctl(*hd,GCRYCTL_SET_CCM_length,params,sizeof(params));
if(err){error(“gcry_cipher_ctl”,err)}
}
void*加密(配置、常量void*明文、void**标记){
gcry\u cipher\u hd\t hdEncrypt;
准备(配置和hdEncrypt);
void*cipherText=malloc(config.messageSize);
gcry\u error\u t err=gcry\u cipher\u encrypt(hdEncrypt,cipherText,config.messageSize,明文,config.messageSize);
if(err){error(“gcry\u cipher\u encrypt”,err);}
*tag=malloc(config.authTagLength);
err=gcry\u cipher\u gettag(hdEncrypt,*tag,config.authTagLength);
if(err){error(“gcry\u cipher\u encrypt”,err);}
gcry_cipher_close(hdEncrypt);
返回密文;
}
void*解密(配置,void*密文,void*标记){
gcry_密码_hd_t hdDecrypt;
准备(配置和hdDecrypt);
void*recoveredText=malloc(config.messageSize);
gcry\u error\u t err=gcry\u cipher\u decrypt(hdDecrypt,recoveredText,config.messageSize,cipherText,config.messageSize);
if(err){error(“gcry_cipher_decrypt”,err);}
err=gcry\u cipher\u checktag(hdDecrypt,tag,config.authTagLength);
如果(gpg\U错误代码(err)=gpg\U错误校验和){
错误(“身份验证”,err);
}
gcry_cipher_close(hdDecrypt);
返回已恢复的文本;
}
int main(){
const char*plainText=“VNiJkPzAWPFm1234”;
配置配置;
config.key=“1234567890123456”;
config.nonce=“0123456789012”;
config.messageSize=strlen(纯文本)+1;
config.authTagLength=10;
无效*标签;
void*cipherText=encrypt(配置、明文和标记);
char*recoveredText=decrypt(配置、密文、标记);
printf(“解密结果:'%s'\n',recoveredText”);
免费(标签);
免费(密文);
免费(恢复文本);
返回0;
}
示例
#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;
}
该示例没有额外的非加密数据,因此gcry_cipher_ctl的参数[1]设置GCRYCTL_SET_CCM_长度为0。但如果需要,它可以很容易地调整
该功能分为三个部分:
- 准备(设置键、当前值(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;
}
#包括
#包括
#包括
#包括
无效错误(const char*what,gcry\u error\t err){
fprintf(标准,“%s失败:%s\n”,什么,gcry_strerror(err));
出口(1);
}
类型定义结构{
const void*键;
const void*nonce;
大小信息大小;
int-authTagLength;
}配置;
无效准备(配置配置,gcry\u密码\u hd\u t*hd){
gcry\u error\u t err=gcry\u cipher\u open(hd,gcry\u cipher\u AES128,gcry\u cipher\u MODE\u CCM,0);
if(err){error(“gcry_cipher_open”,err);}
err=gcry\u cipher\u 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参数[3];
params[0]=config.messageSize;
参数[1]=0;
params[2]=config.authTagLength;
err=gcry_cipher_ctl(*hd,GCRYCTL_SET_CCM_length,params,sizeof(params));
if(err){error(“gcry_cipher_ctl”,err)}
}
void*加密(配置、常量void*明文、void**标记){
gcry\u cipher\u hd\t hdEncrypt;
准备(配置和hdEncrypt);
void*cipherText=malloc(config.messageSize);
gcry\u error\u t err=gcry\u cipher\u encrypt(hdEncrypt,cipherText,config.messageSize,明文,config.messageSize);
if(err){error(“gcry\u cipher\u encrypt”,err);}
*tag=malloc(config.authTagLength);
err=gcry\u cipher\u gettag(hdEncrypt,*tag,config.authTagLength);
if(err){error(“gcry\u cipher\u encrypt”,err);}
gcry_cipher_close(hdEncrypt);
返回密文;
}
void*解密(配置,void*密文,void*标记){
gcry_密码_hd_t hdDecrypt;
准备(配置和hdDecrypt);
void*recoveredText=malloc(config.messageSize);
gcry\u error\u t err=gcry\u cipher\u decrypt(hdDecrypt,recoveredText,config.messageSize,cipherText,config.messageSize);
if(err){error(“gcry_cipher_decrypt”,err);}
err=gcry\u cipher\u checktag(hdDecrypt,