lundi 31 octobre 2016

04 - Algorithme pour l'authentification et l'intégrité - 2eme Partie (HMAC)


04 - Algorithme pour l'authentification et l'intégrité - 2eme Partie (HMAC)


MAC Message Authentication Code

Le MAC permet de vérifier l'intégrité d'un message,  mais contrairement au SHA, le traitement de vérification n'est plus basé essentiellement sur le contenu du message. Il a été généré avec une clé secrète connu des entités émettrice et destinatrice, cela permet notamment d'authentifier l'expéditeur du message par le destinataire en plus de l'intégrité du contenu. 

Un schéma wiki qui représente très simplement le traitement du MAC.






Authentification_de_message

HMAC keyed-hash message authentication code 

Je pourrais résumé que Le HMAC est une implémentation basé sur le MAC et que cette fonction 
peut être combiné avec différents algorithmes de hachage,  HMAC-MD5,  HMAC-SHA. 

La qualité cryptographique dépend du choix de la fonction de hachage associé.


Exemple HMAC avec un SHA1 (wiki)

Keyed-Hash_Message_Authentication_Code




TODO













Lien utiles
Keyed-Hash_Message_Authentication_Code
Voir exemple ci-dessous


Note : java version in work, dont use yet, must fixe bug on sha256

C program  source, reference

tests/test-sha256.c
sha256.c


package test;

import static test.SHA256.SHA256Vector;

/** * Created by bordi on 30/10/2016. */public class HMAC {

    int HMAC_BLOCK_SIZE=  64;
    int MAX_DIGEST_SIZE=  32;

    private static final int SHA256_BLOCK_SIZE=64;
    private static final int SHA256_DIGEST_SIZE=32;

    private static final int SHA_256=0;




    /**     * hmac_sha256 - HMAC-SHA256 over data buffer (RFC 2104)     * @key: Key for HMAC operations     * @key_len: Length of the key in bytes     * @data: Pointers to the data area     * @data_len: Length of the data area     * @mac: Buffer for the hash (32 bytes)     * Returns: 0 on success, -1 on failure     */    int hmac_sha256(byte[] key, int key_len, byte[]data,
                    int  data_len, byte[] mac)

    {

        byte[][] _data=new byte[1][data_len];
       _data[0]=data;
        int[] _data_len=new int[1];
        _data_len[0]=data_len;

        return hmac_sha256_vector(key, key_len, 1, _data, _data_len, mac);
    }



    /**     * hmac_sha256_vector - HMAC-SHA256 over data vector (RFC 2104)     * @key: Key for HMAC operations     * @key_len: Length of the key in bytes     * @num_elem: Number of elements in the data vector     * @addr: Pointers to the data areas     * @len: Lengths of the data blocks     * @mac: Buffer for the hash (32 bytes)     * Returns: 0 on success, -1 on failure     */    int hmac_sha256_vector(byte[] key, int key_len, int num_elem,
                           byte[][] addr,  int[] len, byte[] mac)
    {
        byte[] k_pad=new byte[64]; /* padding - key XORd with ipad/opad */        byte[] tk=new byte [32];
        byte[][] _addr=new byte[6][];
        int[]  _len=new int[6];
        int i;

        if (num_elem > 5) {
      /*       * Fixed limit on the number of fragments to avoid having to       * allocate memory (which could fail).       */            return -1;
        }

        /* if key is longer than 64 bytes reset it to key = SHA256(key) */        if (key_len > 64) {
            byte[][] _key=new byte[1][key_len];
            int[] _key_len=new int[1];
            _key_len[0]=key_len;
            _key[0]=key;
            SHA256Vector(1, _key, _key_len, tk);

            key = tk;
            key_len = 32;
        }

   /* the HMAC_SHA256 transform looks like:    *    * SHA256(K XOR opad, SHA256(K 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 */
   /* start out by storing key in ipad */
       SHA256.memset(k_pad, 0);
       System.arraycopy(key, 0, k_pad, 0,key_len);

   /* XOR key with ipad values */        for (i = 0; i < 64; i++)
            k_pad[i] ^= 0x36;

   /* perform inner SHA256 */        _addr[0] = k_pad;
        _len[0] = 64;
        for (i = 0; i < num_elem; i++) {
            _addr[i + 1] = addr[i];
            _len[i + 1] = len[i];
        }
        if (SHA256Vector(1 + num_elem, _addr, _len, mac) < 0)
            return -1;

        SHA256.memset(k_pad, 0);
        System.arraycopy(key, 0, k_pad, 0,key_len);
   /* XOR key with opad values */        for (i = 0; i < 64; i++)
            k_pad[i] ^= 0x5c;

   /* perform outer SHA256 */        _addr[0] = k_pad;
        _len[0] = 64;
        _addr[1] = mac;
        _len[1] = SHA256.SHA256_MAC_LEN;
        return SHA256Vector(2, _addr, _len, mac);
    }

}


SHA256 class add new method

public static int  SHA256Vector(int  num_elem,  byte[][] addr, int [] len,  byte[] mac) {

    int  i;

    SHA256_CTX ctx=new SHA256_CTX();

    SHA256Init(ctx);
    for (i = 0; i < num_elem; i++)
        SHA256Update(ctx, addr[i], len[i]);

    SHA256Final(ctx, mac) ;

    return 0;
}

// TEST main
package test;

import java.util.ArrayList;
import java.util.List;

import static test.SHA256.SHA256Vector;

/** * Created by bordi on 31/10/2016. */public class TestHMAC {

    static class HmacData {
        public HmacData(byte[] key, int key_len, byte[] data, int data_len, byte[] hash) {
            this.key = key;
            this.key_len = key_len;
            this.data = data;
            this.data_len = data_len;
            this.hash=hash;
        }

        byte[] key= new byte[80];
        int key_len;
        byte[] data=new byte[128];
        int data_len;
        byte[] hash=new byte[32];
    };

    static List<HmacData> hmactest=new ArrayList<HmacData>();

    static void fillData() {

        byte[] key0=new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
                0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20};

        byte[] hash0= new byte[]{(byte) 0xa2, 0x1b, 0x1f, 0x5d, 0x4c, (byte) 0xf4, (byte) 0xf7, 0x3a,
                0x4d, (byte) 0xd9, 0x39, 0x75, 0x0f, 0x7a, 0x06, 0x6a,
                0x7f, (byte) 0x98, (byte) 0xcc, 0x13, 0x1c,(byte) 0xb1, 0x6a, 0x66,
                (byte) 0x92, 0x75,(byte) 0x90, 0x21, (byte)0xcf, (byte)0xab, (byte)0x81, (byte)0x81        };

        hmactest.add(new HmacData( key0,32,"abc".getBytes(),3,hash0 ) );

        byte[] key1=new byte[]{  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
                0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20        };

        byte[] hash1=new byte[]{ 0x10, 0x4f,(byte) 0xdc, 0x12, 0x57, 0x32,(byte) 0x8f, 0x08,
                    0x18, 0x4b, (byte)0xa7, 0x31, 0x31,(byte) 0xc5, 0x3c,(byte) 0xae,
                (byte) 0xe6, (byte)0x98,(byte)0xe3, 0x61, 0x19, 0x42, 0x11, 0x49,
                (byte) 0xea, (byte)0x8c, 0x71, 0x24, 0x56, 0x69, 0x7d, 0x30        };

        hmactest.add(new HmacData( key1,32,"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".getBytes(),56,hash1 ) );

    }

    public static void main(String[] args) {


        int  i;
        byte[] hash=new byte[32];
        byte[][] addr=new byte[2][];
        int[] len=new int[2];
        int errors = 0;

        fillData();

        for (i = 0; i < hmactest.size(); i++) {
            StringBuilder hashStr = new StringBuilder();
            System.out.println("SHA256 test case :"+(i + 1));

            addr[0] = ((HmacData) hmactest.get(i)).data;
            len[0] =  ((HmacData) hmactest.get(i)).data.length;
            SHA256Vector(1, addr, len, hash);

            for (int j = 0; j < 32; j++)
                hashStr.append(String.format("%02X", hash[j]));
            System.out.println(hashStr.toString());

            if (hash.equals(((HmacData) hmactest.get(i)).hash ) == false) {
                System.out.println(" FAIL");
                errors++;
            } else                System.out.println(" OK");
/*            if (len[0]>0) {                addr[0] =                        addr[0] = ((HmacData) hmactest.get(i)).data;                len[0] = 1;                addr[1] =                         ((HmacData) hmactest.get(i+1)).data;                len[1] = ((HmacData) hmactest.get(i)).data.length;                SHA256Vector(2, addr, len, hash);                if (hash.equals(((HmacData) hmactest.get(i)).hash ) == false) {                    System.out.println(" FAIL");                    errors++;                } else                    System.out.println(" OK");            }*/            System.out.println("\n");
        }


    }
}


Aucun commentaire:

Enregistrer un commentaire