Linux C openssl aes-128-cbc demo
openssl 各版本下载
https://openssl-library.org/source/old/index.html
#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/evp.h>
#define AES_KEY_BITS 128
#define GCM_IV_SIZE 12
#define GCM_TAG_SIZE 16
int aes_cbc_encrypt(const unsigned char *plaintext,
int plaintext_len, const unsigned char *aad,
int aad_len, const unsigned char *key,
unsigned char *ciphertext, unsigned char *tag)
{
EVP_CIPHER_CTX *ctx = NULL;
int len = 0;
int ciphertext_len = 0;
// 创建并初始化 EVP_CIPHER_CTX 对象
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL);
// 设置加密密钥
EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL);
// 加密明文数据
if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len) > 0)
{
ciphertext_len = len;
}
else
{
printf("Error! \n");
}
// 结束加密过程,并生成认证标签
EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
ciphertext_len += len;
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, GCM_TAG_SIZE, tag);
// 释放EVP_CIPHER_CTX对象
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int aes_cbc_decrypt(const unsigned char *ciphertext,
int ciphertext_len, const unsigned char *aad,
int aad_len, const unsigned char *tag,
const unsigned char *key, unsigned char *plaintext)
{
EVP_CIPHER_CTX *ctx;
int len;
int plaintext_len;
int ret;
// 创建并初始化EVP_CIPHER_CTX对象
ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL);
// 设置解密密钥
EVP_DecryptInit_ex(ctx, NULL, NULL, key, NULL);
// 设置附加的认证数据(可选)
EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len);
// 解密密文数据
EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len);
plaintext_len = len;
// 设置接收到的认证标签
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, GCM_TAG_SIZE, (void *)tag);
// 结束解密过程,如果认证失败则返回错误
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
plaintext_len += len;
// 释放EVP_CIPHER_CTX对象
EVP_CIPHER_CTX_free(ctx);
return ret == 1 ? plaintext_len : -1;
}
int main()
{
unsigned char key[AES_KEY_BITS / 8];
unsigned char iv[GCM_IV_SIZE];
unsigned char plaintext[] = "Hello, AES 128!";
unsigned char ciphertext[sizeof(plaintext)];
unsigned char decryptedtext[sizeof(plaintext)];
unsigned char tag[GCM_TAG_SIZE];
// 生成密钥
if (RAND_bytes(key, sizeof(key)) != 1)
{
printf("error generating AES key.\n");
return 1;
}
printf("key: \n");
for (int i = 0; i < AES_KEY_BITS / 8; i++)
{
printf("0x%0x ", key[i]);
}
printf("\n");
// 生成初始化向量
if (RAND_bytes(iv, sizeof(iv)) != 1)
{
printf("Error generating GCM IV.\n");
return 1;
}
printf("\n");
// 加密明文数据
int ciphertext_len = aes_cbc_encrypt(plaintext, sizeof(plaintext) - 1, NULL, 0, key, ciphertext, tag);
printf("line: %d ciphertext_len: %d Ciphertext: ", __LINE__, ciphertext_len);
for (int i = 0; i < ciphertext_len; i++)
{
printf("%02x", ciphertext[i]);
}
printf("\n");
printf("line: %d Tag: ", __LINE__);
for (int i = 0; i < GCM_TAG_SIZE; i++)
{
printf("%02x", tag[i]);
}
printf("\n");
// 解密密文数据
int decryptedtext_len = aes_cbc_decrypt(ciphertext, ciphertext_len, NULL, 0, tag, key, decryptedtext);
decryptedtext[decryptedtext_len] = '\0';
printf("line: %d Decrypted text: %s\n", __LINE__, decryptedtext);
return 0;
}
编译:
gcc main.c -o main -lssl -lcrypto
使用:
./main