[从0到1搭嵌入式工程]常用加密方法之AES加解密及密码生成和获取、cyassl库

在项目中,遇到两个终端之间的传输,就会遇到数据加密的问题,比如使用P2P协议音视频和命令的传输。这时,对于加密方法的选择,往往使用AES就可以满足需求了。

下文中还会介绍密码的生成和获取。

AES: 高级加密标准。是一种对称分组加密算法。 对称的意思是加密端和解密端使用相同的密码。分组的意思是把数据分成一小块一小块,进行加密。

AES加密相对于DES(数据加密标准),速度更快,安全级别更高,对称加密本身的速度也很快,所以我们在使用AES加密时,不需要过分担心加解密本身对资源的过多占用。一般来说,密钥越长,运行的速度就越慢,应该根据的我们实际需要的安全级别来选择,一般来说,RSA建议采用1024位的数字,ECC建议采用160位,AES采用128位(16字节)即可。

AES加密的特点: 加密前和加密后,数据长度不会发生改变。

在选择了AES加密之后, 还需要选择AES的加密模式,下面是四种常见的加密模式:

主要来自于:https://www.cnblogs.com/liangxuehui/p/4651351.html

1,ECB 电话本模式

将需要加密的数据分成若干个相同的小段,然后对每一小段分别进行加密。合在一起,就是密文。

优点: 1.简单;2.有利于并行计算;3.误差不会被传送;

缺点: 1.不能隐藏明文的模式;2.可能对明文进行主动攻击(不知道怎么个攻击方法);

2,CBC密码分组链接模式

优点:1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。

缺点:1.不利于并行计算;2.误差传递(前面的密文要传递给下一次加密);3.需要初始化向量IV

3,CFB密码反馈模式

优点:1.隐藏了明文模式;2.分组密码转化为流模式;3.可以及时加密传送小于分组的数据;

缺点:1.不利于并行计算;2.误差传送:一个明文单元损坏影响多个单元;3.唯一的IV;

4,OFB输出反馈模式

优点:1.隐藏了明文模式;2.分组密码转化为流模式;3.可以及时加密传送小于分组的数据;

缺点:1.不利于并行计算;2.对明文的主动攻击是可能的;3.误差传送:一个明文单元损坏影响多个单元;

CFB和OFB没有用过,不知道什么时候适用。

对于嵌入式来说, AES加密可以使用cyassl 3.3.0,https://download.csdn.net/download/bingyu880101/10689018

以下围绕这个库的API展开。

首先是ECB模式,分块加密,需要自己分块,AesEncryptDirect一次只能对16个字节 128位进行加密。

Aes g_aes;
char encrypt_buf[16] = {0};
char encrypt_key[20] = {0};
char data_buf[1024] = {0};
int data_len = 0;

{
	int encrypt_block_len = data_len/16;
	AesSetKeyDirect(&g_aes, (const unsigned char *)encrypt_key, 16, NULL, AES_ENCRYPTION);
	int i = 0;
	for(i=0; i<encrypt_block_len; i++)
	{
		AesEncryptDirect(&g_aes, (unsigned char *)encrypt_buf, (const unsigned char*)(data_buf + 16*i));
		memcpy(data_buf+16*i, encrypt_buf, 16);
	}
}

然后是CBC模式,需要设置IV值,加密端和解密端需要设置一样的IV值。这里设置为NULL;对于不够16个字节的数据,我们保留原文,不进行加密处理。对于CBC方式,也可以自己分段,每次加密16字节,但是在循环时,每一次都必须调用AesSetKey,对IV值进行重置。

Aes g_aes;
char encrypt_buf[1024] = {0};
char encrypt_key[20] = {0};
char data_buf[1024] = {0};
int data_len = 0;

{
	AesSetKey(&g_aes, (const unsigned char *)encrypt_key, 16, NULL, AES_ENCRYPTION);
	AesCbcEncrypt(&g_aes, (unsigned char *)encrypt_buf, (const unsigned char*)(data_buf), (data_len/16 * 16));
	memcpy(data_buf, encrypt_buf, (data_len/16 * 16));
}

对于解密,操作是一样的。 在AesSetKey时,最后的参数需要传入 AES_DECRYPTION。

对数据的加解密,对于音频,因为数据量小,另外从中间截取就可以播放,所以需要全加密,而对于视频数据来说,因为数据量较大,而P帧的解析又依赖于I帧,同时在I帧中自身也有对数据的校验,所以只需要对I帧的前32个字节加密,就可以保证视频数据不会被窃取。

下面是密码生成和获取方式

密码在设备启动时随机生成一次,每隔一段时间,定期随机生成, 然后通过HTTPS协议,上报到后台服务器,手机app去连接设备时,如果密码认证失败,就去后台获取最新的密码,再次连接。

随机密码串的生成方式:

Nonce是或Number once的缩写,在密码学中Nonce是一个只被使用一次的任意或非重复的随机数值。

这里用时间戳做种子,随机生成数,映射出一个字符串,作为nonce密码。生成一个15位的字符串,然后在用密码的时候,在第16位赋值一个字符 '0' 过去凑成16位的密码。

char NonceChars[63] = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789”;
int gen_nonce(unsigned int length, char* nonce, unsigned int size)
{
	unsigned int i = 0;
	struct timeval tv;
	unsigned int seed;
	int chars_len = strlen(NonceChars);

	if(size <= length)
	{
		return -1;
	}

	(void)gettimeofday(&tv, NULL);
	seed = (int)tv.tv_usec+tv.tv_sec+time(NULL);
	(void)srand(seed);
	
	for(i=0;i<length;i++)
	{
		*nonce = NonceChars[rand()%chars_len];
		nonce++;
	}

	*nonce = '\0';
	return 0;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值