消息认证码(Massage Authentication Code)用来检查消息的完整性和真实性。消息认证码的输入为任意长度的消息和发送者与接收者之间共享的密钥,输出为固定长度的数据,该数据被称作MAC值、Tag或T。发送者与接收者判断这个MAC判断消息完整性和真实性
消息认证码的实现
- 单项散列算法实现,这类方法统称为HMAC,与SHA1算法结合称为HMAC-SHA1,与SHA256算法结合称为HMAC-SHA256,与MD5算法结合称为HMAC-MD5
- 分组密码实现,采用CBC模式称作CBC-MAC,还有CMAC
- 认证加密算法实现,是对称加密算法和消息认证码的结合,有GCM和CCM
HMAC-SHA256例子
要打开以下宏
MBEDTLS_MD_C 使能MD层接口
MBEDTLS_SHA256_C 若使用HMAC-SHA256则需使能SHA256
MBEDTLS_SHA1_C 若使用HMAC-SHA1则需使能SHA1
#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 “:” ",
buf[i], i len - 1 ? “\n”:“”);
}
}
int main(void)
{
uint8_t mac[32];
char secret = “Jefe”;
char msg = “what do ya want for nothing?”;
mbedtls_md_context_t ctx<span class="token punctuation">;</span>
<span class="token keyword">const</span> mbedtls_md_info_t <span class="token operator">*</span>info<span class="token punctuation">;</span>
<span class="token function">mbedtls_md_init</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
info <span class="token operator">=</span> <span class="token function">mbedtls_md_info_from_type</span><span class="token punctuation">(</span>MBEDTLS_MD_SHA256<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_md_setup</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> info<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_printf</span><span class="token punctuation">(</span><span class="token string">"\n md info setup, name: %s, digest size: %d\n"</span><span class="token punctuation">,</span>
<span class="token function">mbedtls_md_get_name</span><span class="token punctuation">(</span>info<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">mbedtls_md_get_size</span><span class="token punctuation">(</span>info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_md_hmac_starts</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> secret<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>secret<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_md_hmac_update</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> msg<span class="token punctuation">,</span> <span class="token function">strlen</span><span class="token punctuation">(</span>msg<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_md_hmac_finish</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> mac<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dump_buf</span><span class="token punctuation">(</span><span class="token string">"\n md hmac-sha-256 mac:"</span><span class="token punctuation">,</span> mac<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>mac<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_md_free</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
注意和计算SHA256 api接口区别
运行结果
openssl验证
openssl dgst -sha256 -hmac Jefe -hex text
- 1
GCM例子
要注意打开以下宏
MBEDTLS_AES_C 使能AES接口
MBEDTLS_CIPHER_C 使能cipher接口
MBEDTLS_GCM_C 使能GCM模式
MBEDTLS_AES_ROM_TABLES 使用预定义S盒,节省ram
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include “mbedtls/cipher.h”
#include “mbedtls/platform.h”
/*
[Keylen = 128]
[IVlen = 96]
[PTlen = 128]
[AADlen = 128]
[Taglen = 128]
Count = 0
Key = c939cc13397c1d37de6ae0e1cb7c423c
IV = b3d8cc017cbb89b39e0f67e2
PT = c3b3c41f113a31b73d9a5cd432103069
AAD = 24825602bd12a984e0092d3e448eda5f
CT = 93fe7d9e9bfd10348a5606e5cafa7354
Tag = 0032a1dc85f1c9786925a2e71d8272dd
*/
//密钥
static uint8_t key[] =
{
0xc9, 0x39, 0xcc, 0x13, 0x39, 0x7c, 0x1d, 0x37,
0xde, 0x6a, 0xe0, 0xe1, 0xcb, 0x7c, 0x42, 0x3c
};
//初始化向量
static uint8_t iv[] =
{
0xb3, 0xd8, 0xcc, 0x01, 0x7c, 0xbb, 0x89, 0xb3,
0x9e, 0x0f, 0x67, 0xe2,
};
//明文
static uint8_t pt[] =
{
0xc3, 0xb3, 0xc4, 0x1f, 0x11, 0x3a, 0x31, 0xb7,
0x3d, 0x9a, 0x5c, 0xd4, 0x32, 0x10, 0x30, 0x69
};
//相关数据
static uint8_t add[] =
{
0x24, 0x82, 0x56, 0x02, 0xbd, 0x12, 0xa9, 0x84,
0xe0, 0x09, 0x2d, 0x3e, 0x44, 0x8e, 0xda, 0x5f
};
//密文
static uint8_t ct[] =
{
0x93, 0xfe, 0x7d, 0x9e, 0x9b, 0xfd, 0x10, 0x34,
0x8a, 0x56, 0x06, 0xe5, 0xca, 0xfa, 0x73, 0x54
};
//消息认证码tag
static uint8_t tag[] =
{
0x00, 0x32, 0xa1, 0xdc, 0x85, 0xf1, 0xc9, 0x78,
0x69, 0x25, 0xa2, 0xe7, 0x1d, 0x82, 0x72, 0xdd
};
#define assert_exit(cond, ret)
do { if (!(cond)) {
printf(" !. assert: failed [line: %d, error: -0x%04X]\n", LINE, -ret);
goto cleanup;
} } while (0)
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 “:” ",
buf[i], i len - 1 ? “\n”:“”);
}
}
int main(void)
{
int ret;
size_t len;
uint8_t buf[16], tag_buf[16];
mbedtls_cipher_context_t ctx<span class="token punctuation">;</span>
<span class="token keyword">const</span> mbedtls_cipher_info_t <span class="token operator">*</span>info<span class="token punctuation">;</span>
<span class="token function">mbedtls_cipher_init</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span>
info <span class="token operator">=</span> <span class="token function">mbedtls_cipher_info_from_type</span><span class="token punctuation">(</span>MBEDTLS_CIPHER_AES_128_GCM<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_cipher_setup</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> info<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_printf</span><span class="token punctuation">(</span><span class="token string">"\n cipher info setup, name: %s, block size: %d\n"</span><span class="token punctuation">,</span>
<span class="token function">mbedtls_cipher_get_name</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token function">mbedtls_cipher_get_block_size</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_cipher_setkey</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token operator">*</span><span class="token number">8</span><span class="token punctuation">,</span> MBEDTLS_ENCRYPT<span class="token punctuation">)</span><span class="token punctuation">;</span>
ret <span class="token operator">=</span> <span class="token function">mbedtls_cipher_auth_encrypt</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> iv<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>iv<span class="token punctuation">)</span><span class="token punctuation">,</span> add<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>add<span class="token punctuation">)</span><span class="token punctuation">,</span>
pt<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>pt<span class="token punctuation">)</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token operator">&</span>len<span class="token punctuation">,</span> tag_buf<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert_exit</span><span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert_exit</span><span class="token punctuation">(</span><span class="token function">memcmp</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> ct<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>ct<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert_exit</span><span class="token punctuation">(</span><span class="token function">memcmp</span><span class="token punctuation">(</span>tag_buf<span class="token punctuation">,</span> tag<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dump_buf</span><span class="token punctuation">(</span><span class="token string">"\n cipher gcm auth encrypt:"</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dump_buf</span><span class="token punctuation">(</span><span class="token string">"\n cipher gcm auth tag:"</span><span class="token punctuation">,</span> tag_buf<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">mbedtls_cipher_setkey</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> key<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token operator">*</span><span class="token number">8</span><span class="token punctuation">,</span> MBEDTLS_DECRYPT<span class="token punctuation">)</span><span class="token punctuation">;</span>
ret <span class="token operator">=</span> <span class="token function">mbedtls_cipher_auth_decrypt</span><span class="token punctuation">(</span><span class="token operator">&</span>ctx<span class="token punctuation">,</span> iv<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>iv<span class="token punctuation">)</span><span class="token punctuation">,</span> add<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>add<span class="token punctuation">)</span><span class="token punctuation">,</span>
ct<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>ct<span class="token punctuation">)</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token operator">&</span>len<span class="token punctuation">,</span> tag<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert_exit</span><span class="token punctuation">(</span>ret <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> ret<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">assert_exit</span><span class="token punctuation">(</span><span class="token function">memcmp</span><span class="token punctuation">(</span>buf<span class="token punctuation">,</span> pt<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>pt<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">dump_buf</span><span class="token punctuation">(</span><span class="token string">"\n cipher gcm auth decrypt:"</span><span class="token punctuation">,</span> buf<span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
cleanup:
mbedtls_cipher_free(&ctx);
return(0);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
运行结果