在以下函数的基础上,改写为 使用 CTR/OFB/CFB 加密方式。提供修改后的完整代码
#include "aes_crypto.h"
#include <openssl/err.h>
#include <string.h>
#include <stdio.h>
int aes_init() {
// 初始化OpenSSL库
if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)) {
return AES_ERR_INIT_FAILED;
}
return AES_SUCCESS;
}
void aes_cleanup() {
// 清理OpenSSL资源
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
}
int aes_generate_key(int key_len, AES_KEY *key) {
if (!key || (key_len != 128 && key_len != 192 && key_len != 256)) {
return AES_ERR_INVALID_INPUT;
}
// 生成随机密钥
if (RAND_bytes(key->key, key_len / 8) != 1) {
return AES_ERR_KEY_GEN_FAILED;
}
// 生成随机初始化向量
if (RAND_bytes(key->iv, sizeof(key->iv)) != 1) {
return AES_ERR_KEY_GEN_FAILED;
}
key->key_len = key_len;
return AES_SUCCESS;
}
int aes_save_key(const AES_KEY *key, const char *filename) {
if (!key || !filename) {
return AES_ERR_INVALID_INPUT;
}
FILE *fp = fopen(filename, "wb");
if (!fp) {
return AES_ERR_KEY_SAVE_FAILED;
}
// 写入密钥长度
if (fwrite(&key->key_len, sizeof(int), 1, fp) != 1) {
fclose(fp);
return AES_ERR_KEY_SAVE_FAILED;
}
// 写入密钥
int key_bytes = key->key_len / 8;
if (fwrite(key->key, 1, key_bytes, fp) != key_bytes) {
fclose(fp);
return AES_ERR_KEY_SAVE_FAILED;
}
// 写入IV
if (fwrite(key->iv, 1, sizeof(key->iv), fp) != sizeof(key->iv)) {
fclose(fp);
return AES_ERR_KEY_SAVE_FAILED;
}
fclose(fp);
return AES_SUCCESS;
}
int aes_load_key(AES_KEY *key, const char *filename) {
if (!key || !filename) {
return AES_ERR_INVALID_INPUT;
}
FILE *fp = fopen(filename, "rb");
if (!fp) {
return AES_ERR_KEY_LOAD_FAILED;
}
// 读取密钥长度
if (fread(&key->key_len, sizeof(int), 1, fp) != 1) {
fclose(fp);
return AES_ERR_KEY_LOAD_FAILED;
}
// 验证密钥长度有效性
if (key->key_len != 128 && key->key_len != 192 && key->key_len != 256) {
fclose(fp);
return AES_ERR_KEY_LOAD_FAILED;
}
// 读取密钥
int key_bytes = key->key_len / 8;
if (fread(key->key, 1, key_bytes, fp) != key_bytes) {
fclose(fp);
return AES_ERR_KEY_LOAD_FAILED;
}
// 读取IV
if (fread(key->iv, 1, sizeof(key->iv), fp) != sizeof(key->iv)) {
fclose(fp);
return AES_ERR_KEY_LOAD_FAILED;
}
fclose(fp);
return AES_SUCCESS;
}
int aes_encrypt(const AES_KEY *key, const unsigned char *plaintext,
int pt_len, unsigned char *ciphertext) {
if (!key || !plaintext || !ciphertext || pt_len <= 0) {
return -AES_ERR_INVALID_INPUT;
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
return -AES_ERR_ENCRYPT_FAILED;
}
// 根据密钥长度选择算法
const EVP_CIPHER *cipher = NULL;
switch (key->key_len) {
case 128: cipher = EVP_aes_128_cbc(); break;
case 192: cipher = EVP_aes_192_cbc(); break;
case 256: cipher = EVP_aes_256_cbc(); break;
default:
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_INVALID_INPUT;
}
int len;
int ciphertext_len;
// 初始化加密操作
if (EVP_EncryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_ENCRYPT_FAILED;
}
// 执行加密
if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, pt_len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_ENCRYPT_FAILED;
}
ciphertext_len = len;
// 完成加密
if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_ENCRYPT_FAILED;
}
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int aes_decrypt(const AES_KEY *key, const unsigned char *ciphertext,
int ct_len, unsigned char *plaintext) {
if (!key || !ciphertext || !plaintext || ct_len <= 0) {
return -AES_ERR_INVALID_INPUT;
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
return -AES_ERR_DECRYPT_FAILED;
}
// 根据密钥长度选择算法
const EVP_CIPHER *cipher = NULL;
switch (key->key_len) {
case 128: cipher = EVP_aes_128_cbc(); break;
case 192: cipher = EVP_aes_192_cbc(); break;
case 256: cipher = EVP_aes_256_cbc(); break;
default:
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_INVALID_INPUT;
}
int len;
int plaintext_len;
// 初始化解密操作
if (EVP_DecryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_DECRYPT_FAILED;
}
// 执行解密
if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ct_len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_DECRYPT_FAILED;
}
plaintext_len = len;
// 完成解密
if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1) {
EVP_CIPHER_CTX_free(ctx);
return -AES_ERR_DECRYPT_FAILED;
}
plaintext_len += len;
EVP_CIPHER_CTX_free(ctx);
return plaintext_len;
}
最新发布