消息认证码 hmac

来源:互联网 发布:淘宝拍摄睡袋如何布光 编辑:程序博客网 时间:2024/06/06 05:59

概念介绍

hmac (hash message authentication code) 是用来确认消息的完整性及认证消息的发送者的技术

  1. 完整性,是通过判断hash值来确定的
  2. 认证,是通过对称密码的密钥来完成的

因为是对称密码,所以发送发和接收方事先需要共享密钥

公式:

hmac = hash(msg, key)

发送方发送 msg + hmac
接收方利用公式 hash(msg, key)计算出hmac,然后与接收到的hmac进行对比,如果相同则可确定消息没有被篡改,且是发送者发送的

macOS 上代码封装
头文件 Hmac.h

#ifndef Hmac_h#define Hmac_h#include <stdint.h>#include <vector>class Hmac final {public:    enum struct Algorithm {        Md5,        Sha1,    };public:    typedef std::vector<uint8_t> Data;public:    static Data md5(const Data &msg, const Data &key);    static Data sha1(const Data &msg, const Data &key);public:    ~Hmac();    Hmac(Algorithm alg, const Data &key);    Hmac(Hmac &&hmac) noexcept;    Hmac &operator=(Hmac &&hmac) noexcept;    void update(const Data &data);    Data final();private:    struct HmacImpl *_impl = nullptr;};#endif /* Hmac_h */

实现文件 Hmac.cpp

#include "Hmac.h"#include <CommonCrypto/CommonHMAC.h>#include <assert.h>struct HmacImpl final {public:    HmacImpl(Hmac::Algorithm alg, const void *key, size_t keyLength)    {        CCHmacAlgorithm hmacAlg;        switch (alg) {        case Hmac::Algorithm::Md5:            hmacAlg = kCCHmacAlgMD5;            _hmac.resize(CC_MD5_DIGEST_LENGTH);            break;        case Hmac::Algorithm::Sha1:            hmacAlg = kCCHmacAlgSHA1;            _hmac.resize(CC_SHA1_DIGEST_LENGTH);            break;        }        CCHmacInit(&_ctx, hmacAlg, key, keyLength);    }    void update(const Hmac::Data &data)    {        CCHmacUpdate(&_ctx, data.data(), data.size());    }    Hmac::Data final()    {        CCHmacFinal(&_ctx, _hmac.data());        return _hmac;    }private:    CCHmacContext _ctx;    Hmac::Data _hmac;};#pragma mark -Hmac::~Hmac(){    delete _impl;}Hmac::Hmac(Algorithm alg, const Data &key)    : _impl(new HmacImpl(alg, key.data(), key.size())){}Hmac::Hmac(Hmac &&hmac) noexcept : _impl(hmac._impl){    hmac._impl = nullptr;}Hmac &Hmac::operator=(Hmac &&hmac) noexcept{    assert(&hmac != this);    delete _impl;    _impl = hmac._impl;    hmac._impl = nullptr;    return *this;}void Hmac::update(const Data &data){    _impl->update(data);}Hmac::Data Hmac::final(){    return _impl->final();}#pragma mark -Hmac::Data Hmac::md5(const Data &msg, const Data &key){    Hmac md5(Algorithm::Md5, key);    md5.update(msg);    return md5.final();}Hmac::Data Hmac::sha1(const Data &msg, const Data &key){    Hmac sha1(Algorithm::Sha1, key);    sha1.update(msg);    return sha1.final();}

示例:

#include <string>#include "Hmac.h"int main(){    Hmac::Data key = { 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 }; // 一般是对称密码的密钥    std::string msg = "hello, world";    Hmac::Data data(msg.cbegin(), msg.cend());    auto sha1_mac = Hmac::sha1(data, key);    auto md5_mac = Hmac::md5(data, key);    // ...}
原创粉丝点击