关于security_huks安全模块的知识总结(一)

关于鸿蒙安全模块的代码和内容相关的知识分享总结

1.代码相关

1.1 do{}while(0)

为什么需要do{}while(0)的写法?
在阅读源码时,我们常常会发现这样的书写结构:

do{
……
}while(0)

我们都知道这样写同样是执行内部的代码一次,与最普通的顺序往下写并无结果上的差异,那么为什么工程师们要设计这样的书写结构呢?

这里简单的介绍它的四个作用——当然它的写法肯定不是用来做循环的,而是为了提高代码的健壮性

1.1.1 规范宏定义,实现局部作用域

我们都知道#define是内容的直接替换,当宏定义部分较为复杂时,使用时我们就需要非常小心,比如以下情况:

# define ADD print();out();
int main(){
    if(false)
    	ADD
    return 0;
}

由于宏定义的直接替换,out()函数仍会被执行

那不是加上{}就可以了?
——一般的代码规范我们在结尾都会写上;

# define ADD {print();out();};
int main(){
    if(false)
    	ADD
    return 0;
}

这样写是没有问题的

——但加上else呢?很容易将;多加或者漏加导致编译的错误,所以很多宏定义中会使用do……while(0)将宏定义的模块进行包装来,保证宏定义的使用者能够无编译错误的使用宏

1.2.2 避免使用goto对程序流进行统一的控制

在很多函数中,return之前我们需要进行中间变量空间的free操作,goto能够很好的控制流程

int exmaple{
	struct* ptr = malloc(……);
	int ret = do(……)if(ret){
		goto END;
	}
	ret = doSomething(……)if(ret){
		goto END;
	}
	return 1;
END:
	free(ptr);
	return 0;
}

但是goto虽然好用(在鸿蒙的代码中也可见到少量的goto代码),但是不符合软件工程的结构化,会使得代码结构比较松散,不容易理解,我们可以使用do……while(0)来达到同样的效果

int exmaple{
	struct* ptr = malloc(……);
	do{
		int ret = do(……);
		if(ret){
			break;
		}
		ret = doSomething(……)if(ret){
			break;
		}
	}while(0);
	free(ptr);
	return 0;
}

1.1.3 避免空宏引起的warning

内核中存在不同的架构,空宏的定义在所难免。但是空宏在编译时会warning,为了避免warning,可以使用do{}while(0)来定义空宏

1.1.4 定义一个单独的函数块来实现复杂的操作

当函数比较复杂,变量较多时,不想增加新函数,可以使用do{}while(0)将代码写在里面,里面可以定义变量而不用考虑变量名会同之前或之后的重复

1.2为什么需要lite版本?

Lite使用运行于移动端,有些设备资源非常有限,因此在内存和解析方面必须尽可能减少开销,所以需要轻量版的安全模块功能提供核心功能即可


2.安全相关

2.1 salt的定义

维基百科中对salt的定义如下:
在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。

2.2 为什么需要salt

我们知道数据库中存储的都是加密后的密文,典型的加密算法MD5和SHA都是用于明文的加密的。
验证的时候,通过将输入的数据进行算法加密再与库中数据进行对比,来判断一致性
这就是单向散列函数——为什么说是单向,因为密文无法被解密,我们只能生成而无法反向破解——但是唯一的明文对应唯一的密文,所以用于验证是非常有效的
这样即使数据库中数据泄露,由于都是无法可逆运算的密文,损失也不会太严重。

但是使用单向散列函数就一定安全了吗?
并不是。
如果有人对你的网络行为进行监听,收集了很多你的信息和密码,做成字典对其进行MD5或者SHA运算,然后进行对比,那么破解的可能性还是很大的

这时候就需要加点盐了
Salt 可以是任意字母、数字、或是字母或数字的组合,但必须是随机产生的,存储时就是数据+salt的组合进行存储

这样即使数据库泄露,由于salt的随机性,添加的位置、顺序也可以进行灵活设计,密码被破解的概率也会大大降低

2.3 根据hks_type.h总结的各种算法和模式的类型

  1. 密钥类型分为公钥和私钥
  2. 按照算法和模式分类,密钥又分为:
RSA 支持变长密钥的公共密钥算法的密钥
ECC系列 椭圆曲线密码编码密钥
ED25519 数字签名算法密钥
X25519 密钥协商算法密钥

AES 对称密钥
CHACHA20系列 :
ChaCha系列流密码,作为salsa密码的改良版,具有更强的抵抗密码分析攻击的特性,“20”表示该算法有20轮的加密计算所需的密钥

HMAC 利用密码学中的散列函数来进行消息认证的机制所需的密钥
HKDF
密钥派生函数(KDF)是密码系统的基本组成部分。它的目标是获取一些初始的密钥材料,并从中派生出一个或多个安全强度很大的密钥。

基于HMAC的KDF,称之为HKDF,它可以应用于各种协议和应用程序的构建。HKDF在逻辑上由两个部分组成。第一个部分采用输入密钥材料和“提取”,它是一个固定长度的伪随机密钥K。第二部分则将密钥扩展为几个随机密钥,并以我们需要的长度输出

PBKDF2 将salted hash进行多次重复计算得到的密钥
  1. 密钥的功能:
加密
解密
数字签名
消息认证
WRAP 封装加密
UNWRAP 拆分解密
MAC信息摘要认证
  1. 生成摘要的方法:
单向散列函数
MD5
SHA224 SHA256 SHA384 SHA512
  1. Padding填充方法
OAEP
PSS
PKCS1_V1_5
PKCS5
PKCS7
  1. 加密模式:
ECB
CBC
CTR
OFB
CCM
GCM
  1. 加解密算法:
RSA
ECC

AES
HMAC
HKDF
PBKDF2

ECDH
X25519
ED25519

这里简单介绍一下padding
在这里插入图片描述

2.4 为什么使用Padding

使用padding的目的:对于特定类型的信息来说,大量相同内容的密文部分是容易推测的比如书信的开头敬语:尊敬的,为了防止攻击,我们使用随机长度的padding对数据进行填充,防止攻击者知道长度,展开攻击

2.5 Padding的类型

这里根据鸿蒙安全模块中出现的填充类型进行一个简单的介绍

2.5.1 OAEP

输入:RSA_size(rsa) – 41
输出:和modulus(RSA钥模长)一样长

2.5.2 PSS

在这里插入图片描述

2.5.3 PKCS1_V1_5

填充的规则:

EM = 0x00 || 0x02 || PS || 0x00 || M

其中:
EM是填充后的消息
M是原文
PS是随机数,长度为Len(RSA) - 3 - Len(M)

2.5.4 PKCS5

将数据填充到8的倍数,填充后数据长度的计算公式是 定于元数据长度为x, 填充后的长度是 x + (8 - (x % 8)), 填充的数据是 8 - (x % 8),块大小固定为8字节

2.5.5 PKCS7

假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小;PKCS5只填充到8字节,而PKCS7可以在1-255之间任意填充。

还有前面两篇专门的知识讲解的博客供参考:
鸿蒙安全模块理论知识——MAC,SHA ,hash算法,安全证书相关
加密算法理论概述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国家一级假勤奋研究牲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值