异或加密
解密方式是进行第二次加密后自动解密
#define BUF_SIZE (16384) //16k
/**************************************************************
功能描述: 加密实现
输入参数:
---------------------------------------------------------------
修改作者:
修改日期:
修改说明:新增
***************************************************************/
void log_encrypt(char *data, int dataLen, const char *key)
{
int n = 0;
//对data的每一个字符和key进行按位异或
for(n = 0; n < dataLen; n++)
{
*data = *data ^ 0x09;
data++;
}
}
/**************************************************************
功能描述: log文件加密
输入参数:
---------------------------------------------------------------
修改作者:
修改日期:
修改说明:新增
***************************************************************/
unsigned int log_encryptFile(char *srcFileName)
{
char *key = "google";
int srcFd = -1;
int dstFd = -1;
char *tmpBuf = NULL;
int tmpLen = 0;
int writLen = 0;
log_printf("start: CountFile build date: %s, [%s, %d]\n", __DATE__, __FUNCTION__, __LINE__);
if (!srcFileName)
{
log_printf("srcFileName err![%s, %d]\n", __FUNCTION__, __LINE__);
return EXIT_FAILURE;
}
srcFd = open(srcFileName, O_RDWR);
log_printf("srcFileName:[%s] fd:[%d]\n", srcFileName, srcFd);
if (srcFd < 0)
{
log_printf("open src file failed! [err:%d:%s]\n", errno, strerror(errno));
return EXIT_FAILURE;
}
log_printf("file size:[%d]\n", lseek(srcFd, 0, SEEK_END));
lseek(srcFd, 0, SEEK_SET);
tmpBuf = (char *)malloc(BUF_SIZE);
if (!tmpBuf)
{
log_printf("malloc buf failed! [err:%d:%s]\n", errno, strerror(errno));
close(srcFd);
return EXIT_FAILURE;
}
while((tmpLen = read(srcFd, tmpBuf, BUF_SIZE)) > 0)
{
//加密数据
log_encrypt(tmpBuf, tmpLen, key);
//指针会到此包开始处
lseek(srcFd, -tmpLen, SEEK_CUR);
//写文件
writLen = write(srcFd, tmpBuf, tmpLen);
if (writLen < 0)
{
log_printf("write err,Error: %s\n", strerror(errno));
}
}
close(srcFd);
free(tmpBuf);
log_printf("end: ok: [%s, %d]\n", __FUNCTION__, __LINE__);
return EXIT_SUCCESS;
}
AES加密
AES的算法时间复杂度最低,256K时间如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#define BLOCK_SIZE 16
#define KEY_BIT 256
#define IV_SIZE BLOCK_SIZE
#define KEY_SIZE (KEY_BIT/8)
#define JIEMI_SWITCH 1 //解密开关
// Generate IV
unsigned char iv[IV_SIZE] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
void file_encrypt(char* filename) {
FILE* fp = fopen(filename, "rb");
FILE* outfp = fopen("encrypted.tmp", "wb");
if(fp == NULL) {
printf("Can't open file.\n");
return;
}
// Generate key
unsigned char key[KEY_SIZE];
SHA256((unsigned char*)"google", strlen("google"), key);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if(EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) {
printf("Failed to initialize encryption.\n");
return;
}
unsigned char data_block[BLOCK_SIZE];
unsigned char encrypt_block[BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];
int out_len;
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
unsigned char* buffer = (unsigned char*)malloc(file_size + EVP_MAX_BLOCK_LENGTH);
fread(buffer, 1, file_size, fp);
for(long i = 0; i < file_size; i += BLOCK_SIZE) {
memcpy(data_block, buffer + i, BLOCK_SIZE);
if(i + BLOCK_SIZE > file_size) {
for(int j = file_size % BLOCK_SIZE; j < BLOCK_SIZE; ++j)
data_block[j] = BLOCK_SIZE - (file_size % BLOCK_SIZE);
}
if(EVP_EncryptUpdate(ctx, encrypt_block, &out_len, data_block, BLOCK_SIZE) != 1) {
printf("Failed to encrypt block.\n");
return;
}
fwrite(encrypt_block, 1, out_len, outfp);
}
if(EVP_EncryptFinal_ex(ctx, encrypt_block, &out_len) != 1) {
printf("Failed to finish encryption.\n");
return;
}
fwrite(encrypt_block, 1, out_len, outfp);
free(buffer);
fclose(fp);
fclose(outfp);
rename("encrypted.tmp", filename);
EVP_CIPHER_CTX_free(ctx);
}
void file_decrypt(char* filename) {
FILE* fp = fopen(filename, "rb");
FILE* outfp = fopen("decrypted.tmp", "wb");
if(fp == NULL) {
printf("Can't open file.\n");
return;
}
// Generate key
unsigned char key[KEY_SIZE];
SHA256((unsigned char*)"google", strlen("google"), key);
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
if(EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) {
printf("Failed to initialize decryption.\n");
return;
}
unsigned char data_block[BLOCK_SIZE];
unsigned char decrypt_block[BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];
int out_len;
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
unsigned char* buffer = (unsigned char*)malloc(file_size + EVP_MAX_BLOCK_LENGTH);
fread(buffer, 1, file_size, fp);
for(long i = 0; i < file_size; i += BLOCK_SIZE) {
memcpy(data_block, buffer + i, BLOCK_SIZE);
if(EVP_DecryptUpdate(ctx, decrypt_block, &out_len, data_block, BLOCK_SIZE) != 1) {
printf("Failed to decrypt block.\n");
return;
}
fwrite(decrypt_block, 1, out_len, outfp);
}
if(EVP_DecryptFinal_ex(ctx, decrypt_block, &out_len) != 1) {
printf("Failed to finish decryption.\n");
return;
}
fwrite(decrypt_block, 1, out_len, outfp);
free(buffer);
fclose(fp);
fclose(outfp);
rename("decrypted.tmp", filename);
EVP_CIPHER_CTX_free(ctx);
}
int main(int argc, char **argv) {
if(argc != 2) {
printf("Usage: %s <file>\n", argv[0]);
return 1;
}
char *srcFileName = argv[1];
#if JIEMI_SWITCH
file_encrypt(srcFileName);
printf("加密成功\n");
#else
file_decrypt(srcFileName);
printf("解密成功\n");
#endif
return 0;
}
简单加密
它只是对输入文件进行简单的异或加密操作,使用一个字符串作为密钥
时间复杂度较高,对257K的文件加密,要33s
/**************************************************************
修改作者:wangjj
修改日期:9/25/2023
修改说明:新增
***************************************************************/
unsigned int log_encryptFile(char *srcFileName)
{
char *key = "hualaixiaofang";
int keyLen = strlen(key);
int ch;
int i = 0;
log_printf("encrytFile begin [%s,%d\n]", __FUNCTION__, __LINE__);
if (!srcFileName || !key)
{
log_printf("param err! error:%s [%s,%d]\n", strerror(errno), __FUNCTION__, __LINE__);
return EXIT_FAILURE;
}
FILE *file = fopen(srcFileName, "rb+");
if (file == NULL)
{
log_printf("open file failed!!, error:%s [%s,%d]\n", strerror(errno), __FUNCTION__, __LINE__);
return EXIT_FAILURE;
}
while ((ch = fgetc(file)) != EOF)
{
// 对每个字符和key的对应字符进行加密操作
ch = ch + key[i];
// 将加密后的字符写回文件
fseek(file, -1, SEEK_CUR);
fputc(ch, file);
// 更新key的位置
i = (i + 1) % keyLen;
}
log_printf("encrytFile end [%s,%d\n]", __FUNCTION__, __LINE__);
fclose(file);
}
编译方式
gcc -o decrypt_program_jiemi AES_encrypt.c -lcrypto