2.mbedTLS 单向散列函数 MD5 SHA

单向散列函数是一类满足密码学算法安全属性的特殊散列函数。输入数据通常称为消息,输出数据通常称为消息摘要或简称为摘要,可以用来检测消息的完整性。

单向散列函数较为常用的实现方法包括MD4、MD5、SHA-256、SHA-384/512等。

MD5即Message-Digest Algorithm 5(信息-摘要算法5)
SHA算法的全称为安全散列算法(Secure Hash Algorithms)

单向散列函数应用

1.消息完整性检测
单向散列函数的一个重要应用是对消息的完整性进行检测,例如可以通过比较传输前后消息(或文件)的摘要值来检测是否发生篡改。这样大多数数字签名算法只需要确认消息摘要的真实性即可,验
证消息摘要的真实性等同于验证消息本身的真实性。

2.伪随机数生成器
单向散列函数可以用来构造伪随机数生成算法,它可以用于由单个密钥派生出多个新的密钥,例如TLS1.2协议中的PRF函数。

3.消息认证码
在密码学中,消息认证码可以用于检测消息传输过程中的错误、篡改和伪装,其实现过程依赖于单向散列函数。消息认证码中除了单向散列函数外还加入了共享密钥,该密钥由发送者和接收者共享,因此消息认证码不但可以检测消息在传输过程中是否发生了错误或篡改,还可以对发送者的身份进行认证。

4.数字签名
由于数字签名的计算过程比较耗时,在对消息计算签名之前,通常会使用单向散列函数对消息计算消息摘要,然后对消息摘要进行签名。

5.一次性口令
单向散列函数可构造一次性口令(one-time password)。服务器通常使用一次性口令来认证客户端的合法性,客户端使用单向散列函数计算出令牌和同步资源(例如时间或计数值)的消息摘要,客户端再把消息摘要发送给服务器进行认证。

#define MBEDTLS_MD_C     // 启用MD5 
#define MBEDTLS_SHA224_C // 启用SHA
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA384_C
#define MBEDTLS_SHA512_C

#include "common.h"
#include "mbedtls/platform.h"
#include "mbedtls/md.h"
#include "mbedtls/md5.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"

/*
    以消息"abc"作为测试样本,使用SHA256算法计算消息摘要,SHA256的分组长度为64字节,输出32字节的消息摘要。
*/
int sha256_test(void)
{
    uint8_t digest[32] = {0};
    const char *msg = "abc";

    mbedtls_md_context_t ctx;
    const mbedtls_md_info_t *info;

    // 初始化md结构体
    mbedtls_md_init(&ctx);

    // 根据算法类型获得md信息指针
    info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);

    // 设置 md 结构体,完成 md 结构体内部接口初始化
    mbedtls_md_setup(&ctx, info, 0);

    // 获取单向散列算法名称
    // 获取单向散列算法输出消息摘要长度
    mbedtls_printf("md info setup, name: %s, digest size: %d\n",
                   mbedtls_md_get_name(info), mbedtls_md_get_size(info));

    // md 启动接口
    mbedtls_md_starts(&ctx);

    {
        // md 更新接口,处理输入数据,包括消息预处理和计算
        mbedtls_md_update(&ctx, (const unsigned char *)msg, strlen(msg));

        // md 完成接口,输出消息摘要结果
        mbedtls_md_finish(&ctx, digest);

        mbedtls_printf("1 md sha-256 digest:\n");
        for (int i = 0; i < 32; i++)
        {
            mbedtls_printf("%02x ", digest[i]);
        }
        mbedtls_printf("\n\n");
    }

    {
        // md 更新接口,处理输入数据,包括消息预处理和计算
        mbedtls_md_update(&ctx, (const unsigned char *)msg, strlen(msg));

        // md 完成接口,输出消息摘要结果
        mbedtls_md_finish(&ctx, digest);

        mbedtls_printf("2 md sha-256 digest:\n");
        for (int i = 0; i < 32; i++)
        {
            mbedtls_printf("%02x ", digest[i]);
        }
        mbedtls_printf("\n\n");
    }

    // 释放 md 结构体
    mbedtls_md_free(&ctx);

    return 0;
}

void md5_test()
{
    int ret;
    uint8_t digest[16] = {0};
    char str[] = "Hello, world!";

    if ((ret = mbedtls_md5((uint8_t *)str, 13, digest)) != 0)
    {
        mbedtls_exit(MBEDTLS_EXIT_FAILURE);
    }

    mbedtls_printf("MD5('%s') = ", str);
    for (int i = 0; i < 16; i++)
    {
        mbedtls_printf("%02x", digest[i]);
    }
    mbedtls_printf("\n\n");
}

int main()
{
    printf("\n\n");

    md5_test();

    sha256_test();

    return 0;
}


你可能感兴趣的:(SSL,ssl)