如何使用 AES128 CBC 在 C 语言中使用 OPENSSL 更快地进行加密

问题描述 投票:0回答:1

代码工作正常,只是我希望它更快,但不确定如何做。该代码的作用如下:该代码递归地加密指定目录及其所有子目录的内容。 encrypt_file函数用于加密目录及其子目录中的每个文件。 encrypt_directory 函数使用 readdir 读取目录中的每个条目,并检查它是常规文件还是目录。如果它是常规文件,它会使用 encrypt_file 函数对文件进行加密,并将“.enc”附加到文件名中。如果是目录,则递归调用自身来处理子目录。

加密本身是使用 CBC 模式下的 AES 算法完成的,具有随机生成的密钥和 IV(初始化向量)。密钥和 IV 写入加密文件的开头,后面是文件的加密内容。 EVP_EncryptUpdate 函数用于按块加密文件,EVP_EncryptFinal_ex 用于完成加密并将最终的密文块写入输出文件。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "dirent.h"
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/aes.h>

#define AES_BLOCK_SIZE 16

int encrypt_file(const char* in_filename, const char* out_filename)
{
    EVP_CIPHER_CTX* ctx;
    int len;
    int ciphertext_len;
    FILE* in_file, * out_file;
    unsigned char key[AES_BLOCK_SIZE];
    unsigned char iv[AES_BLOCK_SIZE];
    unsigned char in_buf[AES_BLOCK_SIZE];
    unsigned char out_buf[AES_BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];

    /* Generate random key and IV */
    if (!RAND_bytes(key, AES_BLOCK_SIZE))
        return 0;
    if (!RAND_bytes(iv, AES_BLOCK_SIZE))
        return 0;

    /* Initialize the encryption context */
    if (!(ctx = EVP_CIPHER_CTX_new()))
        return 0;
    if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
        return 0;

    /* Open the input and output files */
    if (!(in_file = fopen(in_filename, "rb")))
        return 0;
    if (!(out_file = fopen(out_filename, "wb")))
        return 0;

    /* Write the key and IV to the output file */
    if (fwrite(key, 1, AES_BLOCK_SIZE, out_file) != AES_BLOCK_SIZE)
        return 0;
    if (fwrite(iv, 1, AES_BLOCK_SIZE, out_file) != AES_BLOCK_SIZE)
        return 0;

    /* Encrypt and write the ciphertext to the output file */
    while ((len = fread(in_buf, 1, AES_BLOCK_SIZE, in_file))) {
        if (1 != EVP_EncryptUpdate(ctx, out_buf, &ciphertext_len, in_buf, len))
            return 0;
        if (fwrite(out_buf, 1, ciphertext_len, out_file) != ciphertext_len)
            return 0;
    }

    /* Finalize the encryption */
    if (1 != EVP_EncryptFinal_ex(ctx, out_buf, &ciphertext_len))
        return 0;
    if (fwrite(out_buf, 1, ciphertext_len, out_file) != ciphertext_len)
        return 0;

    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    fclose(in_file);
    fclose(out_file);

    return 1;
}

void encrypt_directory(const char* dir_name)
{
    DIR* dir;
    struct dirent* entry;
    char path[1024];

    /* Open the directory specified by dir_name */
    if (!(dir = opendir(dir_name)))
        return;

    /* Read each entry from the directory */
    while ((entry = readdir(dir))) {
        /* Ignore the current and parent directories */
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;

        /* Construct the full path of the entry */
        snprintf(path, sizeof(path), "%s/%s", dir_name, entry->d_name);

        /* If the entry is a directory, call encrypt_directory recursively */
        if (entry->d_type == DT_DIR) {
            encrypt_directory(path);
        }
        /* If the entry is a file, encrypt it */
        else if (entry->d_type == DT_REG) {
            /* Construct the output filename by appending ".enc" to the original filename */
            char out_filename[1024];
            strcpy(out_filename, path);
            strcat(out_filename, ".enc");

            /* Call encrypt_file to encrypt the file */
            if (encrypt_file(path, out_filename)) {
                /* If encryption was successful, delete the original file */
                remove(path);
            }
        }
    }

    /* Close the directory */
    closedir(dir);
}

我尝试过线程处理,结果一团糟。

c encryption openssl aes encryption-symmetric
1个回答
0
投票

这个项目是纯软件:https://github.com/kokke/tiny-AES-c/blob/master/aes.c 我们将它用于缓慢且简单的 MCU,如果速度不太重要,则可以完美工作

© www.soinside.com 2019 - 2024. All rights reserved.