用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("\n###CYH: before size: %d, final_size is %d\n\n", 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("\n"); } } printf("\n"); } 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("\n\n###CYH: key: "); for (i = 0; i < 32; i++) printf("%02x", key[i]); printf(" size: %d bytes\n", (int)sizeof(key)); printf("###CYH: iv: "); for (i = 0; i < 16; i++) printf("%02x", iv[i]); printf(" size: %d bytes\n", (int)sizeof(iv)); //get normal file size
    stat("./uImage",&statbuf); filesize=statbuf.st_size; printf("###CYH: get uImage file size: %d bytes\n", 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\n", ret); //加密
    printf("\n###CYH: before padding, buf(size: %d bytes):\n", filesize); printf_buff(buf_normal, filesize); after_padding_buf = padding_buf(buf_normal, filesize, &final_size); printf("\n###CYH: after padding, buf(size: %d bytes): \n", 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("\n###CYH: after encrypt: \n"); 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\n", 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("\n###CYH: after decrypt: \n"); printf_buff(buf_decrypt, filesize); // comapare result
    if(!memcmp(after_padding_buf, buf_decrypt, final_size)) { printf("\n###CYH: test success\n\n"); }else { printf("\n###CYH: test failed\n\n"); } // 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\n\n", 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

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM