• HMac基本介绍


    基本介绍

    HMAC(散列消息身份验证码: Hashed Message Authentication Code)

    它不是散列函数,而是采用散列函数(MD5 or 或SHA)与共享密钥一起使用的消息身份验证机制。

    详细见 RFC 2104

    使用场景

    • 服务端生成key,传给客户端;
    • 客户端使用key将帐号和密码做HMAC,生成一串散列值,传给服务端;
    • 服务端使用key和数据库中用户和密码做HMAC计算散列值,比对来自客户端的散列值。

    按照散列函数的不同,可以有如下实现。

    Hmac_MD5,Hmac_sha1,Hmac_sha224,Hmac_sha256,Hmac_sha384,Hmac_sha512。

    Hmac_MD5:

    /**
     * MD5(Key XOR opad, MD5(Key XOR ipad, text))
     *
     * where K is an n byte key
     * ipad is the byte 0x36 repeated 64 times
     * opad is the byte 0x5c repeated 64 times
     * and text is the data being protected(maybe user or password).
     */
    
        memcpy( k_ipad, key, key_len);
        memcpy( k_opad, key, key_len);
    
        /* XOR key with ipad and opad values */
        for (i = 0; i < KEY_IOPAD_SIZE; i++) {
            k_ipad[i] ^= 0x36;
            k_opad[i] ^= 0x5c;
        }
    
        // perform inner MD5
        MD5Init(&context);                    /* init context for 1st pass */
        MD5Update(&context, k_ipad, KEY_IOPAD_SIZE);      /* start with inner pad */
        MD5Update(&context, (unsigned char*)text, text_len); /* then text of datagram */
        MD5Final(hmac, &context);             /* finish up 1st pass */
    
        // perform outer MD5
        MD5Init(&context);                   /* init context for 2nd pass */
        MD5Update(&context, k_opad, KEY_IOPAD_SIZE);     /* start with outer pad */
        MD5Update(&context, hmac, MD5_DIGEST_SIZE);     /* then results of 1st hash */
        MD5Final(hmac, &context);          /* finish up 2nd pass */
    

    Hmac_sha1:

        /**
         * SHA(Key XOR opad, SHA(Key XOR ipad, text))
         *
         * where K is an n byte key
         * ipad is the byte 0x36 repeated 64 times
         * opad is the byte 0x5c repeated 64 times
         * and text is the data being protected(maybe user or password).
         */
    
        memcpy(k_ipad, key, key_len);
        memcpy(k_opad, key, key_len);
        /* XOR key with ipad and opad values */
        for (i = 0; i < KEY_IOPAD_SIZE; i++) {
            k_ipad[i] ^= 0x36;
            k_opad[i] ^= 0x5c;
        }
    
        // perform inner SHA
        SHA_Init(&context);                    /* init context for 1st pass */
        SHA_Bytes(&context, k_ipad, KEY_IOPAD_SIZE);      /* start with inner pad */
        SHA_Bytes(&context, text, text_len);   /* then text of datagram */
        SHA_Final(&context, hmac);             /* finish up 1st pass */
    
        // perform outer SHA
        SHA_Init(&context);                   /* init context for 2nd pass */
        SHA_Bytes(&context, k_opad, KEY_IOPAD_SIZE);     /* start with outer pad */
        SHA_Bytes(&context, hmac, SHA1_DIGEST_SIZE);     /* then results of 1st hash */
        SHA_Final(&context, hmac);          /* finish up 2nd pass */
    

    Hmac_sha224,mac_sha256 和 Hmac_sh啊类似,把SHA换成SHA224或SHA256即可,注意 ipad和opad的长度为64.

    Hmac_sha384:Hmac_sha512和Hmac_sha384类似,把SHA384换成SHA512即可,注意 ipad和opad的长度为128.

        /**
         * SHA384(Key XOR opad, SHA(Key XOR ipad, text))
         *
         * where K is an n byte key
         * ipad is the byte 0x36 repeated 128 times
         * opad is the byte 0x5c repeated 128 times
         * and text is the data being protected(maybe user or password).
         */
    
        memcpy(k_ipad, key, key_len);
        memcpy(k_opad, key, key_len);
        /* XOR key with ipad and opad values */
        for (i = 0; i < KEY_IOPAD_SIZE128; i++) {
            k_ipad[i] ^= 0x36;
            k_opad[i] ^= 0x5c;
        }
    
        // perform inner SHA384
        SHA384_Init(&context);                    /* init context for 1st pass */
        SHA384_Bytes(&context, k_ipad, KEY_IOPAD_SIZE128);      /* start with inner pad */
        SHA384_Bytes(&context, text, text_len); /* then text of datagram */
        SHA384_Final(&context, hmac);             /* finish up 1st pass */
    
        // perform outer SHA384
        SHA384_Init(&context);                   /* init context for 2nd pass */
        SHA384_Bytes(&context, k_opad, KEY_IOPAD_SIZE128);     /* start with outer pad */
        SHA384_Bytes(&context, hmac, SHA384_DIGEST_SIZE);     /* then results of 1st hash */
        SHA384_Final(&context, hmac);          /* finish up 2nd pass */
    

      

    C implement at github: https://github.com/mygityf/cipher/blob/master/cipher/hmac.c

    Done.

  • 相关阅读:
    一个男人该有的气质
    有没有想过,也许一辈子你都是个小人物
    System.IO.File.WriteAllText("log.txt", "dddd");
    cn_windows_10_enterprise_version_1703_updated_june_2017_x64_dvd_10720588.iso
    Visual Studio 2015 update 3各版本下载地址
    优麒麟 16.04 LTS(长期支持)版本
    干货!最全羽毛球技术动态分解gif图
    添加缓存 绝对时间过期
    C#缓存absoluteExpiration、slidingExpiration两个参数的疑惑
    无法解析依赖项。“Microsoft.Net.Http 2.2.29”与 'Microsoft.Net.Http.zh-Hans
  • 原文地址:https://www.cnblogs.com/voipman/p/5320237.html
Copyright © 2020-2023  润新知