openssl AES ecb 加解密文件

#define AES_BLACK_SIZE  (1024)

int aes_128_ecb_encrypt_file(const char *file_path, unsigned char *key, const char *encrypt_file_path)
{
    EVP_CIPHER_CTX *ctx;

    const int block_size = AES_BLACK_SIZE;
    int read_size = 0, write_size = 0, encrypt_len = 0;
    unsigned char read_buff[AES_BLACK_SIZE] = {0};
    unsigned char encrypt_data[AES_BLACK_SIZE+32] = {0};


	FILE *rfd = fopen(file_path, "rb");
	if(!rfd)
    {
		printf("fopen file: %s failed", file_path);
		return -1;
	}

	FILE *wfd = fopen(encrypt_file_path, "wb");
	if(!wfd)
    {
		printf("fopen file: %s failed", encrypt_file_path);
        fclose(rfd);
		return -1;
	}

    if(!(ctx = EVP_CIPHER_CTX_new()))
    {
        printf("EVP_CIPHER_CTX_new error\n");
        goto exit1;
    }

    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
    {        
        printf("EVP_EncryptInit_ex error\n");
        goto exit2;
    }


    /*如果不调用次函数默认的填充方式也是EVP_PADDING_PKCS7*/
    EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);

	while((read_size = fread(read_buff, 1, block_size, rfd)))
    {
        if(1 != EVP_EncryptUpdate(ctx, encrypt_data, &encrypt_len, read_buff, read_size))
        {
            ERR_print_errors_fp(stderr);
            printf("EVP_EncryptUpdate error");
            goto exit2;
        } 
        
        memset(read_buff, 0, sizeof(read_buff));
        write_size = fwrite(encrypt_data, 1, encrypt_len, wfd);
        if(write_size != encrypt_len)
        {
            printf("fwrite one data block failed\n");
            goto exit2;
        }   
    }
    
    if(1 != EVP_EncryptFinal_ex(ctx, encrypt_data, &encrypt_len))
    {
        ERR_print_errors_fp(stderr);
        printf("EVP_EncryptFinal_ex error");
        goto exit2;
    } 
    
    write_size = fwrite(encrypt_data, 1, encrypt_len, wfd);
    if(write_size != encrypt_len)
    {
        printf("fwrite last data block failed\n");
        goto exit2;
    }   


    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    fclose(rfd);
    fclose(wfd);
    return 0;
    
exit2:
    EVP_CIPHER_CTX_free(ctx);
exit1:
    fclose(rfd);
    fclose(wfd);    
    return -1;

}


int aes_128_ecb_decrypt_file(const char *encrypt_file_path, unsigned char *key, const char *decrypt_file_path)
{
    EVP_CIPHER_CTX *ctx;

    const int block_size = 16;
    int read_size = 0, write_size = 0, decrypt_len = 0, count = 0;
    unsigned char read_buff[32] = {0};
    unsigned char decrypt_data[32] = {0};
   
	FILE *rfd = fopen(encrypt_file_path, "rb");
	if(!rfd)
    {
		printf("fopen file: %s failed", encrypt_file_path);
		return -1;
	}

	FILE *wfd = fopen(decrypt_file_path, "wb");
	if(!wfd)
    {
		printf("fopen file: %s failed", encrypt_file_path);
        fclose(rfd);
		return -1;
	}

    if(!(ctx = EVP_CIPHER_CTX_new()))
    {
        printf("EVP_CIPHER_CTX_new error\n");
        goto exit1;
    }
          
    if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL))
    {        
        printf("EVP_DecryptInit_ex error\n");
        goto exit2;
    }
        
    /*如果不调用次函数默认的填充方式也是EVP_PADDING_PKCS7*/
    EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);

	while((read_size = fread(read_buff, 1, block_size, rfd)))
    {
        if(1 != EVP_DecryptUpdate(ctx, decrypt_data, &decrypt_len, read_buff, read_size))
        {
            ERR_print_errors_fp(stderr);
            printf("EVP_DecryptUpdate error\n");
            goto exit2;
        }
        
        memset(read_buff, 0, sizeof(read_buff));
        write_size = fwrite(decrypt_data, 1, decrypt_len, wfd);
        if(write_size != decrypt_len)
        {
            printf("fwrite one data block failed\n");
            goto exit2;
        } 
        
    }

    if(1 != EVP_DecryptFinal_ex(ctx, decrypt_data, &decrypt_len))
    {
        ERR_print_errors_fp(stderr);
        printf("EVP_DecryptFinal_ex error\n");
        goto exit2;
    }
    
    write_size = fwrite(decrypt_data, 1, decrypt_len, wfd);
    if(write_size != decrypt_len)
    {
        printf("fwrite one data block failed\n");
        goto exit2;
    } 


    /* Clean up */
    EVP_CIPHER_CTX_free(ctx);
    fclose(rfd);
    fclose(wfd);
    return 0;

exit2:
    EVP_CIPHER_CTX_free(ctx);
exit1:
    fclose(rfd);
    fclose(wfd);    
    return -1;
}

int sha256_file (const char* path, unsigned char *digest)
{
	char hash[SHA256_DIGEST_LENGTH];
	SHA256_CTX sha256;
	char *buffer = NULL;
	const int bufsize = READ_SIZE;
	int bytes_read = 0;

	FILE *file = fopen(path, "rb");
	if (!file) {
		printf("%s: can not open %s\n", __func__, path);
		return -1;
	}

	SHA256_Init(&sha256);

	buffer = calloc(1, bufsize + 1);
	if (!buffer) {
		printf("%s: malloc failed\n", __func__);
		fclose(file);
		return -1;
	}

	while((bytes_read = fread(buffer, 1, bufsize, file)))
		SHA256_Update(&sha256, buffer, bytes_read);

	SHA256_Final(digest, &sha256);

	fclose(file);
	free(buffer);

	return 0;
}

main.c 接口测试

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>   
#include <errno.h>


#include <openssl/err.h>
#include <openssl/sha.h>
#include <openssl/aes.h>
#include <openssl/evp.h>  
#include <openssl/buffer.h>

#define SHA256_DIGEST_LENGTH 32

void print_hex_hash(unsigned char* digest, int length)
{
	int i;
	for(i=0; i < length; i++)
		printf("%02x", digest[i]);

    printf("\n");
}


int main()
{
    const char *file_path = "/home/lyxin/share/test/sha256/test.zip";
    const char *encrypt_file_path = "/home/lyxin/share/test/sha256/testen.zip";
    const char *decrypt_file_path = "/home/lyxin/share/test/sha256/testde.zip";
    

    sha256_file(file_path, sha256_digest);    
    print_hex_hash(sha256_digest, SHA256_DIGEST_LENGTH);

    aes_128_ecb_encrypt_file(file_path, key, encrypt_file_path);
    sleep(5);
    aes_128_ecb_decrypt_file(encrypt_file_path, key, decrypt_file_path);

    memset(sha256_digest, 0, sizeof(sha256_digest));
    sha256_file(decrypt_file_path, sha256_digest);    
    print_hex_hash(sha256_digest, SHA256_DIGEST_LENGTH);

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值