2016-12-23 30 views
3

組み込みプロジェクトで使用するために私自身のHMAC-SHA256を実装する必要があります。私はそれを動作させるのに問題があります。私も擬似コードを取得することはできません、手で計算された、私は間違って何かをしていることを知っている!HMACの実装 - 擬似コード

私のpseduoコードの計算。

key = 0x6d796b6579000000000000000000000000000000000000000000000000000000

o_key_pad = 0x31253739255c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c

:ウィキペディア

1 function hmac (key, message) 
2  if (length(key) > blocksize) then 
3   // keys longer than blocksize are shortened 
4   key = hash(key) 
5  end if 
6  if (length(key) < blocksize) then 
7   // keys shorter than blocksize are zero-padded 
8   key = key ∥ zeroes(blocksize - length(key)) 
9  end if 
10 
11  // Where blocksize is that of the underlying hash function 
12  o_key_pad = [0x5c * blocksize] ⊕ key 
13  i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR) 
14  // Where ∥ is concatenation 
15  return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) 
16 end function 

で図に続いて、私は、キー= "にmykey" とメッセージ= "HelloWorldの" のためのバイ手計算は、私は、次の取得を行うとi_key_pad = 0x5b4f5d534f363636363636363636363636363636363636363636363636363636

hash(i_key_pad ∥ message) = 6fb2e91de7b8b5ec6283846ff7245cd6eb4a4fd26056b529bd42d99fcf3314d2

0d76a16089f85cd2169bb64b6f2c818e6a404a218896483fcd97fee5cce185ae

答えて

5

全体のHMACキーの長さを固定し、内側と外側のパディングをcalulating、あなたがその出力と同じではない根本的なハッシュ関数のブロックサイズを使用する必要がサイズ。これは、関数が操作する入力ブロックのサイズです。 SHA256の場合、ブロックサイズは512ビット(64バイト)、出力サイズは256ビット(32バイト)です。

結果が、ブロックサイズとして32を使用した場合の結果です。正しい長さを使用

keyo_key_padi_key_padのみ回限りそれぞれ005c又は36バイト末尾と、基本的に同じであるBLOCKSIZE。

8bf029764919f9e35249d0d55ffb8fd6c62fe23a85c1515e0120c5005aa813d5 

と最終値(hash(o_key_pad ∥ hash(i_key_pad ∥ message)))は次のとおりです:

内部ハッシュの結果(すなわちhash(i_key_pad ∥ message)がある。私は、OpenSSLのHMACの実装から取得する結果と一致して

7fdfaa9c9c0931f52d9ebf2538bc99700f2e771f3af1c1d93945c2256c11aedd 

0

これは私が思いついたコードです:

/** 
* This function takes in a key, the length of that key, a message (null terminated) and a pointer to a char[32] or greater array 
* It calculates the HMAC-SHA256 of the given key message combo and returns the resulting code in binary form, 32 hex pairs 
1 @example ???? todo function hmac (key, message) 
2  if (length(key) > blocksize) then 
3   // keys longer than blocksize are shortened 
4   key = hash(key) 
5  end if 
6  if (length(key) < blocksize) then 
7   // keys shorter than blocksize are zero-padded 
8   key = key ∥ zeroes(blocksize - length(key)) 
9  end if 
10 
11  // Where blocksize is that of the underlying hash function 
12  o_key_pad = [0x5c * blocksize] ⊕ key 
13  i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR) 
14  // Where ∥ is concatenation 
15  return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) 
16 end function 
* @param key todo 
* @param length todo 
* @param message todo 
* @param hmac todo 
*/ 
void hmac(char key[], int length, char message[], char *hmac){ 
    int msgLen = strlen(message); //get the length of the message to be encrypted 
    char keyFinal[BLOCK_SIZE] = {0}; //setup array for the data to go into 

    if(length > BLOCK_SIZE){   //if the given data is too long, hash it 
     shaHash(key, keyFinal); 
    } 
    if(length < BLOCK_SIZE){   //if the given data is too short, pad it with 0x00 
     int i; 
     for(i = 0; i < BLOCK_SIZE; i++){ 
      if(i < length){    //read in the data 
       keyFinal[i] = key[i]; 
      }else{      //if there is no more data to read, read in zeros 
       keyFinal[i] = 0x00; 
      } 
     } 
    } 
    if(length == BLOCK_SIZE){  //if the given data is the right size, transfer it to keyFinal 
     int i; 
     for(i = 0; i < BLOCK_SIZE; i++){ 
      keyFinal[i] = key[i]; 
     } 
    } 

    char oKeyPad[BLOCK_SIZE] = {0}; //setup the oKeyPad 
    char iKeyPad[BLOCK_SIZE] = {0}; //setup the ikeypad 

    int i; 
    for(i = 0; i < BLOCK_SIZE; i++){ //for each item in key final, xor it with O_KEY_PAD and I_KEY_PAD 
     oKeyPad[i] = keyFinal[i]^O_KEY_PAD; 
     iKeyPad[i] = keyFinal[i]^I_KEY_PAD; 
    } 

    char iandmesg[BLOCK_SIZE+MAX_SHA]; //setup the inner hash ikeypad concat with message 
    char hash_iandmesg[HASH_LEN] = {0};  //get ready to get bytes back from the hashing function 

    //make the message to be hashed, ikeypad concatinated with message 
    for(i = 0; i < BLOCK_SIZE; i++){ //read in ikeypad 
     iandmesg[i] = iKeyPad[i]; 
    } 
    for(i = BLOCK_SIZE; i < (msgLen + BLOCK_SIZE); i++){ //read in message 
     iandmesg[i] = message[i-BLOCK_SIZE]; 
    } 

    shaHash_len(iandmesg, (msgLen+BLOCK_SIZE), hash_iandmesg); //create the inner hash (ikeypad + message) 

    char oandihash[(BLOCK_SIZE + HASH_LEN)]; //setup the outter hash, okeypad + (hash of ikeypad + message) 

    //make the message to be hashed, okeypad concatinated with the hash of (ikeypad + message) 
    for(i = 0; i < BLOCK_SIZE; i++){ //read in okeypad 
     oandihash[i] = oKeyPad[i]; 
    } 
    for(i = BLOCK_SIZE; i < (BLOCK_SIZE + HASH_LEN); i++){ //read in hash of ikeypad + message 
     oandihash[i] = hash_iandmesg[i-BLOCK_SIZE]; 
    } 

    //return the result of the hash of (okeypad + hash(ikeypad + message)) 
    shaHash_len(oandihash, (BLOCK_SIZE + HASH_LEN), hmac); 
}