• 【Linux】C语言实现对文件的加密算法


    异或加密

    解密方式是进行第二次加密后自动解密

    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    AES加密

    AES的算法时间复杂度最低,256K时间如下:
    在这里插入图片描述
    在这里插入图片描述

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #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 \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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137

    简单加密

    它只是对输入文件进行简单的异或加密操作,使用一个字符串作为密钥
    时间复杂度较高,对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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    编译方式

    gcc -o decrypt_program_jiemi AES_encrypt.c -lcrypto

    mbedtls加密

    
    #include 
    #include 
    #include 
    #include "mbedtls/aes.h"
    
    #define KEY_SIZE 32 // 256位密钥
    #define BLOCK_SIZE 16 // 128位分组
    
    int log_encryptFile(const char* input_file) {
        
        // 打开输入文件
        FILE* input = fopen(input_file, "rb");
        if (input == NULL) {
            printf("无法打开输入文件\n");
            return -1;
        }
        const unsigned char key[KEY_SIZE] = "wjj";
        // 计算输入文件大小
        fseek(input, 0, SEEK_END);
        long input_size = ftell(input);
        fseek(input, 0, SEEK_SET);
    
        // 创建输出缓冲区
        unsigned char* output = (unsigned char*)malloc(input_size);
        if (output == NULL) {
            printf("内存分配失败\n");
            fclose(input);
            return -1;
        }
    
        // 初始化加密上下文
        mbedtls_aes_context ctx;
        mbedtls_aes_init(&ctx);
        mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE * 8);
    
        // 加密文件内容
        unsigned char input_block[BLOCK_SIZE];
        unsigned char output_block[BLOCK_SIZE];
        size_t offset = 0;
        size_t read_bytes;
        while ((read_bytes = fread(input_block, 1, BLOCK_SIZE, input)) > 0) {
            mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, input_block, output_block);
            memcpy(output + offset, output_block, read_bytes);
            offset += read_bytes;
        }
    
        // 关闭文件和释放资源
        fclose(input);
        mbedtls_aes_free(&ctx);
    
        // 打开输入文件,以写入方式覆盖原内容
        input = fopen(input_file, "wb");
        if (input == NULL) {
            printf("无法打开输入文件\n");
            free(output);
            return -1;
        }
    
        // 将加密后的内容写入输入文件
        fwrite(output, 1, input_size, input);
    
        // 关闭文件和释放资源
        fclose(input);
        free(output);
    
        printf("文件加密完成\n");
    
        return 0;
    }
    
    int log_decryptFile(const char* input_file) {
        // 打开输入文件
        FILE* input = fopen(input_file, "rb");
        if (input == NULL) {
            printf("无法打开输入文件\n");
            return -1;
        }
        const unsigned char key[KEY_SIZE] = "wjj";
        // 计算输入文件大小
        fseek(input, 0, SEEK_END);
        long input_size = ftell(input);
        fseek(input, 0, SEEK_SET);
    
        // 创建输出缓冲区
        unsigned char* output = (unsigned char*)malloc(input_size);
        if (output == NULL) {
            printf("内存分配失败\n");
            fclose(input);
            return -1;
        }
    
        // 初始化解密上下文
        mbedtls_aes_context ctx;
        mbedtls_aes_init(&ctx);
        mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE * 8);
    
        // 解密文件内容
        unsigned char input_block[BLOCK_SIZE];
        unsigned char output_block[BLOCK_SIZE];
        size_t offset = 0;
        size_t read_bytes;
        while ((read_bytes = fread(input_block, 1, BLOCK_SIZE, input)) > 0) {
            mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, input_block, output_block);
            memcpy(output + offset, output_block, read_bytes);
            offset += read_bytes;
        }
    
        // 关闭文件和释放资源
        fclose(input);
        mbedtls_aes_free(&ctx);
    
        // 打开输入文件,以写入方式覆盖原内容
        input = fopen(input_file, "wb");
        if (input == NULL) {
            printf("无法打开输入文件\n");
            free(output);
            return -1;
        }
    
        // 将解密后的内容写入输入文件
        fwrite(output, 1, input_size, input);
    
        // 关闭文件和释放资源
        fclose(input);
        free(output);
    
        printf("文件解密完成\n");
    
        return 0;
    }
    // 编译方式:gcc -o decrypt-jiami AES_encrypt.c -lmbedtls -lmbedcrypto -lmbedx509
    int main(int argc, char **argv) {
        if(argc != 2) {
            printf("Usage: %s \n", argv[0]);
            return 1;
        }
    
        char *srcFileName = argv[1];
    
        if (log_encryptFile(srcFileName) != 0) {
            printf("加密文件失败\n");
            return -1;
        }
        printf("文件加密完成\n");
     
    
    #if 0
        if (log_decryptFile(srcFileName) != 0) {
            printf("解密文件失败\n");
            return -1;
        }
    
       printf("解密成功\n");
    #endif 
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157

    编译方式

    gcc -o decrypt-jiami AES_encrypt.c -lmbedtls -lmbedcrypto -lmbedx509
    
    • 1
  • 相关阅读:
    System Generator学习——将代码导入System Generator
    C到C++入门基础知识
    数字孪生在工业制造中的应用领域及技术体系构建
    搞定面试官 - 可以介绍一下 MySQL InnoDB 引擎的索引模型嘛?
    java计算机毕业设计记事网页(附源码、数据库)
    快解析结合泛微OA
    跨语言调用C#代码的新方式-DllExport
    Dubbo框架实现RPC远程调用包括nacos的配置和初始化
    yolov5的onnx推断示例和思路记录(包含detect.py的最新源码解读)
    计算机毕业设计(附源码)python综合众筹网站
  • 原文地址:https://blog.csdn.net/qq_21688871/article/details/133299235