HMAC算法

一、简介

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)。 HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。也就是说HMAC通过将哈希算法(SHA1, MD5)与密钥进行计算生成摘要。

HMAC与哈希算法一起使用。

二、实现原理

请添加图片描述

HMAC的计算公式为:
HMAC(K,M)=H(K⊕opad∣H(K⊕ipad∣M))

运算步骤:
(1)检查密钥K的长度。如果K的长度大于B则先使用摘要算法计算出一个长度为L的新密钥。如果K的长度小于B,则在其后面追加0来使其长度达到B。
(2)将上一步生成的B字长的密钥字符串与ipad做异或运算,得到比特序列ipadkey。
(3)将ipadkey附加在消息M的开头;
(4)使用哈希函数H计算第3步中生成的数据流的信息摘要值。
(5) 将第1步生成的B字长密钥字符串与opad做异或运算,得到opadkey。
(6)再将第4步得到的结果填充到opadkey之后。
(7)使用哈希函数H计算第6步中生成的数据流的信息摘要值,输出结果就是最终的HMAC值。

三、Hmac代码实现

对hmac-sha256 加密使用示例

  • swift系统代码
public func hmacsha256(_ key: String) -> String {
        let cData = self.cString(using: .utf8) ?? []
        let cKey = key.cString(using: .utf8) ?? []
        
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        
        CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), cKey, key.count, cData, self.count, &digest)
        let outData = Data(bytes: digest, count: Int(CC_SHA256_DIGEST_LENGTH))
        let hash = outData.hexString()
        return hash
    }
  • C语言代码示例
#define B SHA256_CBLOCK
#define L (SHA256_DIGEST_LENGTH)
#define K (SHA256_DIGEST_LENGTH * 2)

#define I_PAD 0x36
#define O_PAD 0x5C

/*
 * HMAC(H, K) == H(K ^ opad, H(K ^ ipad, text))
 *
 *    H: Hash function (sha256)
 *    K: Secret key
 *    B: Block byte length
 *    L: Byte length of hash function output
 *
 * https://tools.ietf.org/html/rfc2104
 */
void hmac_sha256(const unsigned char *key, int key_len, const unsigned char *d, size_t n,
                 unsigned char *md, unsigned int *md_len) {
    assert(key);
    assert(d);
    assert(md);

    if (*md_len < SHA256_DIGEST_LENGTH){
        return;
    }

    SHA256_CTX shaCtx;
    uint8_t kh[SHA256_DIGEST_LENGTH];

    /*
     * If the key length is bigger than the buffer size B, apply the hash
     * function to it first and use the result instead.
     */
    if (key_len > B) {
        SHA256_Init(&shaCtx);
        SHA256_Update(&shaCtx, key, key_len);
        SHA256_Final(kh, &shaCtx);
        key_len = SHA256_DIGEST_LENGTH;
        key = kh;
    }

    /*
     * (1) append zeros to the end of K to create a B byte string
     *     (e.g., if K is of length 20 bytes and B=64, then K will be
     *     appended with 44 zero bytes 0x00)
     * (2) XOR (bitwise exclusive-OR) the B byte string computed in step
     *     (1) with ipad
     */
    uint8_t kx[B];
    for (size_t i = 0; i < key_len; i++) kx[i] = I_PAD ^ key[i];
    for (size_t i = key_len; i < B; i++) kx[i] = I_PAD ^ 0;

    /*
     * (3) append the stream of data 'text' to the B byte string resulting
     *     from step (2)
     * (4) apply H to the stream generated in step (3)
     */
    SHA256_Init(&shaCtx);
    SHA256_Update(&shaCtx, kx, B);
    SHA256_Update(&shaCtx, d, n);
    SHA256_Final(md, &shaCtx);

    /*
     * (5) XOR (bitwise exclusive-OR) the B byte string computed in
     *     step (1) with opad
     *
     * NOTE: The "kx" variable is reused.
     */
    for (size_t i = 0; i < key_len; i++) kx[i] = O_PAD ^ key[i];
    for (size_t i = key_len; i < B; i++) kx[i] = O_PAD ^ 0;

    /*
     * (6) append the H result from step (4) to the B byte string
     *     resulting from step (5)
     * (7) apply H to the stream generated in step (6) and output
     *     the result
     */
    SHA256_Init(&shaCtx);
    SHA256_Update(&shaCtx, kx, B);
    SHA256_Update(&shaCtx, md, SHA256_DIGEST_LENGTH);
    SHA256_Final(md, &shaCtx);

    *md_len = SHA256_DIGEST_LENGTH;
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值