zoukankan      html  css  js  c++  java
  • 用openssl aes256 api实现文件加解密-带例程,兼容openssl enc -aes-256-cbc命令

    本文参考链接:

      https://blog.csdn.net/u010144805/article/details/78627599

      https://blog.csdn.net/u010144805/article/details/78627599

      https://blog.csdn.net/zisehuoxia/article/details/106214671

    感谢他们的分享!

     下面是我自己的尝试过程,记录一下:

    我的ubuntu版本: 16.04 64位

    openssl 版本:OpenSSL 1.0.2g  1 Mar 2016  (输入命令 openssl version -a查看)

    于是我下了源码包回来, 链接: http://www.linuxfromscratch.org/blfs/view/7.9/postlfs/openssl.html

    从源码中将相关文件移到一个目录里面(Makefile, main.c,uImage自己新建,  uImage.enc uImage.dec是生成文件)

    移植后的目录结构:

     

    改过的一些文件内容:

     aes_locl.h

    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    
     
    #define STRICT_ALIGNMENT 1
    #undef PEDANTIC
    #undef FULL_UNROLL
    #undef OPENSSL_SMALL_FOOTPRINT
    
    #  define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
    
    #  define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
    
    typedef long long i64;
    typedef unsigned long long u64;
    typedef unsigned int u32;
    typedef unsigned short u16;
    typedef unsigned char u8;
    
    # define MAXKC   (256/32)
    # define MAXKB   (256/8)
    # define MAXNR   14

     

     main.c

    #include <aes_locl.h>
    #include <openssl/modes.h>
    #include <openssl/aes.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    unsigned char *padding_buf(unsigned char *buf,int size, int *final_size) {//注释2
    
        unsigned char *ret = NULL;
        int pidding_size = AES_BLOCK_SIZE - (size % AES_BLOCK_SIZE);
        int i;
    
        *final_size = size + pidding_size;
        //printf("
    ###CYH: before size: %d, final_size is %d
    
    ", size, *final_size);
    
        ret = (unsigned char *)malloc(size+pidding_size);
        memcpy( ret, buf, size);
        if (pidding_size!=0) {
            for (i =size;i < (size+pidding_size); i++ ) {
                ret[i] = pidding_size;
            }
        }
    
        return ret;
    }
    
    void printf_buff(unsigned char *buff,int size) {
    
        int i = 0;
        for (i=0;i<size;i ++ ) {
            printf( "%02X ", (unsigned char)buff[i] );
            if ((i+1) % 16 == 0) {
                printf("
    ");
            }
        }
        printf("
    ");
    }
    
    int main() 
    {
        //unsigned char key[32] = "1234567890";
        unsigned char key[32] = {0x11, 0x22, 0x33, 0x44, 0x55,0x66, 0x77, 0x88}; //注意:这里必须是16进制
    
        //unsigned char iv[16] = "123456";
        unsigned char iv[16] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; // 注意:这里必须是16进
        unsigned char iv_copy[16];
        unsigned char *buf_normal;
        unsigned char *buf_encrypt;
        unsigned char *buf_decrypt;
        unsigned char *after_padding_buf;
        AES_KEY aesKey;
    
        int fd_normal, fd_encrypt, fd_decrypt;
        unsigned int filesize = 0;
        struct stat statbuf;
        int ret = 0, i;
        int final_size = 0;
    
        //print key and iv content
        printf("
    
    ###CYH: key: ");
        for (i = 0; i < 32; i++)
            printf("%02x", key[i]);
        printf(" size: %d bytes
    ", (int)sizeof(key));
    
        printf("###CYH:  iv: ");
        for (i = 0; i < 16; i++)
            printf("%02x", iv[i]);
        printf(" size: %d bytes
    ", (int)sizeof(iv));
    
        //get normal file size
        stat("./uImage",&statbuf);
        filesize=statbuf.st_size;
        printf("###CYH: get uImage file size: %d bytes
    ", filesize);
    
        //malloc memory
        buf_normal = malloc(filesize);
    
        //get normal file data
        fd_normal = open("./uImage", O_RDONLY);
        ret = read(fd_normal, buf_normal, filesize);
        printf("###CYH: read uImage buf size: %d bytes
    ", ret);
        
        //加密
        printf("
    ###CYH: before padding, buf(size: %d bytes):
    ", filesize);
        printf_buff(buf_normal, filesize);
        after_padding_buf = padding_buf(buf_normal, filesize, &final_size);
        printf("
    ###CYH: after padding, buf(size: %d bytes): 
    ", final_size);
        printf_buff(after_padding_buf, final_size);
        buf_encrypt = malloc(final_size);
        buf_decrypt = malloc(final_size);
    
        memcpy(iv_copy, iv, 16);//向量在运算过程中会被改变,为了之后可以正常解密,拷贝一份副本使用
        private_AES_set_encrypt_key(key, 256, &aesKey);
        AES_cbc_encrypt(after_padding_buf, buf_encrypt, final_size, &aesKey, iv_copy, 1);
    
        printf("
    ###CYH: after encrypt: 
    ");
        printf_buff(buf_encrypt, final_size);
    
        fd_encrypt = open("./uImage.enc", O_CREAT|O_RDWR, 0755);
        ret = write(fd_encrypt, buf_encrypt, final_size);
        printf("###CYH: have wrote %d bytes to uImage.enc
    ", ret);
        close(fd_encrypt);
    
        //解密
        memcpy(iv_copy, iv, 16);
        private_AES_set_decrypt_key(key, 256, &aesKey);
        AES_cbc_encrypt(buf_encrypt, buf_decrypt, final_size, &aesKey, iv_copy, 0);
    
        printf("
    ###CYH: after decrypt: 
    ");
        printf_buff(buf_decrypt, filesize);
    
        // comapare result
        if(!memcmp(after_padding_buf, buf_decrypt, final_size)) {
            printf("
    ###CYH: test success
    
    ");    
        }else {
            printf("
    ###CYH: test failed
    
    ");    
        }
    
        // write decrypt file
        fd_decrypt = open("./uImage.dec", O_CREAT|O_RDWR, 0755);
        ret = write(fd_decrypt, buf_decrypt, filesize);
       printf("###CYH: have wrote %d bytes to uImage.dec ", ret); close(fd_decrypt);
    return 0; }

    Makefile

    CC := gcc
    AS := as
    LD := ld
    INCLUDE := -I.
    INCLUDE += -I ./include
    DEFINES :=
    #DEFINES += -D AUTO_INIT
    CFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE)
    LIBS :=
    LIBS += -lpthread
    LDFLAGS :=
    
    .PHONY : all clean
    
    TARGET = aestest
    
    OBJS = main.c aes_cbc.c aes_core.c cbc128.c
    
    all: $(TARGET)
    
    $(TARGET): $(OBJS)
        $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
    
    clean:
        rm -f $(TARGET)
        rm -f *.o
        rm -f uImage.*

    uImage

    testopenssltestopenssltestopenssltestopenssltestopenssltestopenssltestopenssltestopenssl

     

    测试

    测试过程操作及输出:
    bert@bert-virtual-machine:/media/bert/work/testopenssl$ make clean && make && ./aestest
    rm -f aestest
    rm -f *.o
    rm -f uImage.*
    gcc -g -Wall -O3  -I. -I ./include -o aestest main.c aes_cbc.c aes_core.c cbc128.c   -lpthread
    
    

    ###CYH: key: 1122334455667788000000000000000000000000000000000000000000000000 size: 32 bytes
    ###CYH:  iv: 11223344556600000000000000000000 size: 16 bytes
    ###CYH: get uImage file size: 89 bytes
    ###CYH: read uImage buf size: 89 bytes
    
    
    ###CYH: before padding, buf(size: 89 bytes):
    74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74 6F
    70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73 73
    6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74
    6F 70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73
    73 6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73
    74 6F 70 65 6E 73 73 6C 0A
    
    
    ###CYH: after padding, buf(size: 96 bytes):
    74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74 6F
    70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73 73
    6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74
    6F 70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73
    73 6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73
    74 6F 70 65 6E 73 73 6C 0A 07 07 07 07 07 07 07 (补全) 
    
    

    ###CYH: after encrypt:
    D4 9D E2 C7 49 70 71 4A 9A CD 85 52 5D D6 74 70
    6C 47 D2 84 96 4D 21 A0 61 A7 D7 FB D9 3A 49 5E
    7A 75 72 11 11 3D 47 2B 85 33 D9 DC 94 AA 16 11
    1E F7 76 74 23 CC A9 51 6D 83 54 FE 11 EE C0 BE
    19 EF B8 E4 FE 2E 17 2D D8 43 B5 8F FF F8 FA 95
    41 64 12 58 58 06 8D 2E 56 48 3A F9 AB 5D 3B 16
    
    
    ###CYH: have wrote 96 bytes to uImage.enc
    
    
    ###CYH: after decrypt:
    74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74 6F
    70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73 73
    6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73 74
    6F 70 65 6E 73 73 6C 74 65 73 74 6F 70 65 6E 73
    73 6C 74 65 73 74 6F 70 65 6E 73 73 6C 74 65 73
    74 6F 70 65 6E 73 73 6C 0A
    
    
    ###CYH: test success
    
    
    ###CYH: have wrote 89 bytes to uImage.dec 

    可见上面已经测试成功了

     

    利用openssl命令对通过代码生成的加密文件uImage.enc进行解密:

    openssl enc -aes256 -d -p -K 1122334455667788 -iv 112233445566 -in uImage.enc -out uImage.dec   (大写的K)

     没报错, 测试通过

    加上p选项可以把key打印出来

    可能会出现的报错:

    如果代码里面的iv和key写的是字符串,那可能会出现以下错误:

    bert@bert-virtual-machine:/media/bert/work/testopenssl$ openssl enc -aes-256-cbc -d -p -K 1122334455667788 -iv 112233445566 -in uImage.enc -out uImage.dec
    salt=0000000000000000
    key=1122334455667788000000000000000000000000000000000000000000000000
    iv =11223344556600000000000000000000
    bad decrypt
    140185284007576:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:529:

    如果你不做padding buf这一步(或者你全补的是0),也就是补成16的倍数,你会遇到下面报错

    salt=0100000000000000
    key=1122334455667788000000000000000000000000000000000000000000000000
    iv =11223344556600000000000000000000
    bad decrypt
    140648214177432:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:evp_enc.c:518:

     

    如果key不对你可能会遇到报错

    openssl enc -aes256 -d -p -K 1122334455667788 -iv 112233445566 -in uImage.enc -out uImage.dec   (大写的K) --> 大写的K,写成小写的k

     

    bert@bert-virtual-machine:/media/bert/work/testopenssl$ openssl enc -aes-256-cbc -d -p -k 1122334455667788 -iv 112233445566 -in uImage.enc -out uImage.dec
    bad magic number

     

  • 相关阅读:
    socket.io笔记
    node express+socket.io实现聊天室
    socket.io中 connect与connection的区别
    css clip-path的polygon属性绘制多边形
    vue 3.0
    angular
    项目总结61:IDEA远程调试linux下的tomcat
    Java深入学习28:Redisson分布式锁的使用
    Java深入学习27:Java反射
    Java深入学习28:Runnable和Callable
  • 原文地址:https://www.cnblogs.com/cheyihaosky/p/13467341.html
Copyright © 2011-2022 走看看