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