Mbedtls学习--单向散列函数
单向散列函数
原理
满足密码学算法安全属性的特殊散列函数,保证数据的完整性,抵御篡改攻击,原数据称作消息,计算后的输出称为摘要,在通信中,Bob接受Alice发来的消息及摘要,通过相同的算法计算摘要比对以验证消息是否被篡改。
性质
输入长度可变,输出长度固定,计算过程应当高效率,具备单向性。
- 抗弱碰撞性,对于给定$a$,能找到$b$使得$h(a)=h(b)$不可行
- 抗强碰撞性,给定一个输出$z$,能够找到$h(a)=z$不可行
应用
消息完整性检测、伪随机数生成器、数字签名、消息认证码
单向散列函数实现方法
MD算法
- MD4:散列碰撞已被攻破
- MD5:抗碰撞性已被攻破
SHA算法
SHA0/SHA1不再使用
- SHA2:包括SHA256,SHA384,SHA512
- SHA3:更为安全
SHA256
处理步骤:
- 预处理
- 消息填充
- 消息分割
- 设置初始摘要值 $H^{(0)}$
- 准备常量$K^{256}_{i}$
- 哈希计算
- 消息调度
- 初始化工作寄存器
- 更新工作寄存器
- 计算消息摘要
Mbedtls单项散列函数
generic_sum
计算散列值
generic_sum SHA256 <file name>
头文件和函数接口
#include "mbedtls/md.h"
接口 | 描述 |
---|---|
mbedtls_md_init | 初始化md结构体 |
mbedtls_md_info_from_type | 根据算法类型得到md信息结构体指针 |
mbedtls_md_setup | 初始化md结构体 |
mbedtls_md_get_name | 获得单向散列算法名称 |
mbedtls_md_get_size | 获取单向散列算法输出消息摘要长度 |
mbedtls_md_starts | md启动接口 |
mbedtls_md_update | md更新接口,处理输入数据,包括预处理和计算 |
mbedtls_md_finish | md输出消息摘要结果 |
mbedtls_md_free | 释放md结构体 |
依赖
#define MBEDTLS_MD_C
#define MBEDTLS_SHA256_C
示例代码
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "mbedtls/md.h"
#include "mbedtls/platform.h"
static void dump_buf(char *info, uint8_t *buf, uint32_t len)
{
mbedtls_printf("%s", info);
for (int i = 0; i < len; i++) {
mbedtls_printf("%s%02X%s", i % 16 == 0 ? "\n\t":" ",
buf[i], i == len - 1 ? "\n":"");
}
mbedtls_printf("\n");
}
int main(void)
{
uint8_t digest[32];
char *msg = "abc";
mbedtls_md_context_t ctx;
const mbedtls_md_info_t *info;
mbedtls_md_init(&ctx);
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
mbedtls_md_setup(&ctx, info, 0);
mbedtls_printf("\n md info setup, name: %s, digest size: %d\n",
mbedtls_md_get_name(info), mbedtls_md_get_size(info));
mbedtls_md_starts(&ctx);
mbedtls_md_update(&ctx, msg, strlen(msg));
mbedtls_md_finish(&ctx, digest);
dump_buf("\n md sha-256 digest:", digest, sizeof(digest));
mbedtls_md_free(&ctx);
return 0;
}
config头文件
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_PLATFORM_MEMORY
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
#define MBEDTLS_PLATFORM_EXIT_ALT
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
#define MBEDTLS_PLATFORM_PRINTF_ALT
/* mbed TLS modules */
#define MBEDTLS_MD_C
#define MBEDTLS_SHA256_C
#include "mbedtls/check_config.h"
#endif /* MBEDTLS_CONFIG_H */
CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project("hash")
include_directories(./ $ENV{MBEDTLS_BASE}/include)
aux_source_directory($ENV{MBEDTLS_BASE}/library MBEDTLS_SOURCES)
set(SOURCES
${CMAKE_CURRENT_LIST_DIR}/main.c
${CMAKE_CURRENT_LIST_DIR}/mbedtls_config.h
${MBEDTLS_SOURCES})
add_executable(hash ${SOURCES})
运行结果:
mkdir -p build && cd build && cmake .. && make -j32
./hash
md info setup, name: SHA256, digest size: 32
md sha-256 digest:
BA 78 16 BF 8F 01 CF EA 41 41 40 DE 5D AE 22 23
B0 03 61 A3 96 17 7A 9C B4 10 FF 61 F2 00 15 AD
实际应用中,mbedtls_md_update
可以调用多次,不断填充数据。