博客
关于我
OTA升级功能系列一(升级包的加解密)
阅读量:316 次
发布时间:2019-03-04

本文共 2986 字,大约阅读时间需要 9 分钟。

OTA升级包的加解密:从零开始

最近接手一个项目,需要在产品上新增一个OTA升级功能。一开始我以为就是从服务器下载一个程序到本地执行,弹出提示框重启就搞定了。没想到这个过程还涉及很多细节,比如加解密、解压缩、文件校验等等。为了把这些功能加上去,我花了不少时间,现在把这段时间的收获记录下来,也算是对这段工作做了一个总结。

因为涉及的内容太多,所以打算分几篇博文一一叙述。今天就先从文件加解密说起。

OTA升级包的加解密在OTA升级过程中,为了保护产品不受恶意攻击,我们需要对升级包进行加密和解密操作。当我们从服务器下载升级包时,需要先解密,确保文件没有被窃取或植入恶意代码。

那么如何实现加解密操作呢?自己写算法虽然可以,但安全性可能不高。于是想找一个开源库来直接使用。经过搜索,找到了openssl这个库,里面正好有我们需要的加解密功能。

openssl库的编译在使用openssl库的加解密功能之前,首先需要编译库文件。进入指定目录后,依次执行以下命令:

./config./make all

编译完成后,会在目录下生成几个重要的文件,其中libcrypto.a和libssl.a是我们需要的库文件。

openssl头文件说明编译完成后,我们需要编写测试代码来验证加解密的可用性。我们选择使用aes加密算法,头文件位于crypto/aes/目录下。

AES加密文件测试代码编写Makefile文件,用于编译测试代码。编写步骤如下:

touch otaPack.c编写Makefile文件:CC=ccCFLAGS=-O -I../crypto/aes -I../includeOTAPACK_OBJS = otaPack.o ../libcrypto.a ../libssl.a

call:otaPack: $(OTAPACK_OBJS)$(CC) $(CFLAGS) -o $@ $(OTAPACK_OBJS)clean:/bin/rm -f *.o otaPack

编写文件加密和解密函数:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <aes.h>

int main(int argc, char *argv[]) {if (argc < 5) {printf("参数错误!!!\r\n");exit(-1);}char file_in[64];char file_out[64];int mode = -1;char passwd[16+1];if (argv[1] == '-') {if (argv[1][1] == 'd') {mode = AES_DECRYPT;} else if (argv[1][1] == 'e') {mode = AES_ENCRYPT;}}strcpy(file_in, argv[2]);strcpy(file_out, argv[3]);strcpy(passwd, argv[4]);

printf("mode : %d. \r\n", mode);printf("file_in: %s. \r\n", file_in);printf("file_out: %s. \r\n", file_out);printf("passwd: %s. \r\n", passwd);if (mode == AES_DECRYPT) {	_decrypt_file(file_in, file_out, passwd);} else if (mode == AES_ENCRYPT) {	_encrypt_file(file_in, file_out, passwd);}return 0;

}

void _encrypt_file(char *file_in, char *file_out, char *passwd) {FILE *fp_in = fopen(file_in, "r+");FILE *fp_out = fopen(file_out, "w+");unsigned char iv[AES_BLOCK_SIZE];int position = 0;int bytes_read, bytes_write;AES_KEY aes_key;AES_set_encrypt_key(passwd, 128, &aes_key);while (1) {memset(iv, 0, AES_BLOCK_SIZE);bytes_read = fread(indate, 1, AES_BLOCK_SIZE, fp_in);if (bytes_read < AES_BLOCK_SIZE) break;AES_cfb128_encrypt(indate, outdate, bytes_read, &aes_key, iv, &position, AES_ENCRYPT);bytes_write = fwrite(outdate, 1, bytes_read, fp_out);}fclose(fp_in);fclose(fp_out);}

void _decrypt_file(char *file_in, char *file_out, char *passwd) {FILE *fp_in = fopen(file_in, "r+");FILE *fp_out = fopen(file_out, "w+");unsigned char iv[AES_BLOCK_SIZE];int position = 0;int bytes_read, bytes_write;AES_KEY aes_key;AES_set_encrypt_key(passwd, 128, &aes_key);while (1) {memset(iv, 0, AES_BLOCK_SIZE);bytes_read = fread(outdate, 1, AES_BLOCK_SIZE, fp_in);if (bytes_read < AES_BLOCK_SIZE) break;AES_cfb128_encrypt(outdate, decryptdate, bytes_read, &aes_key, iv, &position, AES_DECRYPT);bytes_write = fwrite(decryptdate, 1, bytes_read, fp_out);}fclose(fp_in);fclose(fp_out);}

编译并测试代码:make all

测试文件:touch test.zip test./otaPack -e test.zip encrypt.zip 123456./otaPack -d encrypt.zip decrypt.zip 123456

测试结果表明,解密后的文件无法正常解压。这是因为密码长度不够,aes算法需要16个字符。重新设置16位密码进行测试,发现能够正常解压。

总结:通过这段时间的学习和测试,成功实现了OTA升级包的加解密功能。接下来需要将解密代码移植到开发板上,具体实现会有更多细节需要处理。

转载地址:http://fjnq.baihongyu.com/

你可能感兴趣的文章
Oracle中的rownum 和rowid的用法和区别
查看>>
oracle中的大小写、字符、dual、数字、处理、日期、函数、显/隐式、时间、条件表达式case、decode、to_date、to_char、sysdate
查看>>
oracle从备份归档日志的方法集中回收
查看>>
oracle优化器analyzed,Oracle 学习之 性能优化(十三) 索引
查看>>
Oracle修改字段类型
查看>>
oracle典型安装失败,安装oracle 10失败
查看>>
Oracle内存结构详解(四)--Oracle SGA其他组成部分
查看>>
Oracle分析函数之LEAD和LAG
查看>>
Oracle创建database link(dblink)和同义词(synonym)
查看>>
Oracle和SQL server的数据类型比较
查看>>
oracle用户改名
查看>>
Oracle用游标删除重复数据
查看>>
Oracle监听配置、数据库实例配置等
查看>>
Oracle系列:安装Oracle RAC数据库(二)
查看>>
oracle系统 介绍,ORACLE数据库管理系统介绍
查看>>
oracle获取数据库表、字段、注释、约束等
查看>>
oracle表空间查询维护命令大全之三(暂时表空间)史上最全
查看>>
oracle表访问方式
查看>>
Oracle触发器
查看>>
Oracle计划将ZGC项目提交给OpenJDK
查看>>