zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    min_25筛入门
    [湖南集训]更为厉害/谈笑风生
    [ARC060D] 最良表現
    [CQOI2007]矩形
    [SCOI2009]粉刷匠
    PAT乙级1030
    PAT乙级1028
    PAT乙级1029
    PAT乙级1026
    PAT乙级1027
  • 原文地址:https://www.cnblogs.com/voipman/p/5320237.html
Copyright © 2011-2022 走看看