【OpenSSL】HMAC消息认证码

HMAC消息认证码

  • 哈希运算消息码(Hash-based Message Authentication Code)
  • 与密钥相关的单向散列函数
  • 应用在SSL协议中
  • 消息是否被正确传输
  1. 消息完整性
  2. 消息认证

算法流程

【OpenSSL】HMAC消息认证码_第1张图片

  1. 密钥填充0(填充到与散列函数分组长度一致)
  2. 填充后的密钥与0X36做异或ipad
  3. 与消息内容组合
  4. 第一次与单向散列函数进行散列计算
  5. 填充后密钥与0x5c做异或运算的到opad.
  6. 得到的opad与第一次散列结果做组合
  7. 再做一次散列, 得到最后的MAC值。
  8. 整体过程中密钥有点类似于SALT

HMAC 安全问题

  • 重放攻击
  1. 使用时间戳, nonce随机数解决
  • 无法解决的问题
  1. 无第3方证明,密码发送问题
  2. 防止否认

模拟HMAC消息

模拟消息发送端生成消息

string GetHMAC1() 
{
   unsigned char data[1024] = "HMAC1";
   int data_size = strlen((char*)data);
   //生成MAC存储空间
   unsigned char mac[1024] = { 0 };
   unsigned int mac_size = 0;
   char key[1024] = "123456";
   HMAC(EVP_sha256(), //设置HASH算法
   	key, //共享密钥
   	strlen(key), //密钥长度
   	data,
   	data_size,
   	mac, //返回的消息MAC
   	&mac_size //返回消息MAC长度
   );
   //生成消息,模拟发送消息体
   string msg(mac, mac + mac_size);    //1 . 消息的HMAC
   msg.append(data, data+data_size);  // 2. 消息内容
   return msg;
}

模拟消息接收端验证消息


void TestHMAC(string msg1) 
{
   //string msg1 = GetHMAC1();
   const char* data = msg1.data() + 32; // SHA-256就是32个字节
   int data_size = msg1.size() - 32; //去掉头部
   string hmac(msg1.begin(), msg1.begin() + 32); //拿到发送端生成的hmac

   unsigned char out[1024];
   unsigned int out_size = 0;
   //验证消息完整和验证
   char key[1024] = "123456";
   HMAC(EVP_sha256(),
   	key,
   	strlen(key),
   	(unsigned char*)data, //输入的数据
   	data_size,
   	out, 
   	&out_size
   );
   // 验证生成的HMAC
   string my_hmac(out, out + out_size);
   if (hmac == my_hmac) 
   {
   	cout << "消息HMAC校验成功, no change!" << endl;
   }
   else 
   {
   	cout << "消息HMAC校验失败, message change!" << endl;
   }
}

测试


int main(int argc, char* argv[])
{
   // 测试HMAC
   string msg1 = GetHMAC1();
   TestHMAC(msg1);
   return 0;
}

【OpenSSL】HMAC消息认证码_第2张图片

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