Python code using HMAC library

2

I'm doing a job on encryption for college using HMAC along with SHA256, and I would like to understand what this code does on each line, I'm a bit confused.

#!/usr/bin/env python3
import hashlib
import hmac
from math import ceil

hash_len = 32
def hmac_sha256(key, data):
    return hmac.new(key, data, hashlib.sha256).digest()

def hkdf(length, ikm, salt=b"", info=b""):
    prk = hmac_sha256(salt, ikm)
    t = b""
    okm = b""
    for i in range(ceil(length / hash_len)):
        t = hmac_sha256(prk, t + info + bytes([1+i]))
        okm += t
    return okm[:length]
    
asked by anonymous 10.06.2018 / 18:02

2 answers

0

Although the answer from @Marcelo Uchimura answers the question, I think it does not answer what the code is for, even mentioning that this would be for messages, where it is not point.

HKDF is a KDF using HMAC, there is a definition of it here . Well, a KDF has as input a "not so random" die and another die, which is uniformly random. A good example of use is when a key is agreed via ECDH, since the key is "mathematical response", so it is not indistinguishable from a completely random data, so the use of KDF is necessary. Similarly, you may want to have multiple keys using only one, so HKDF can also be used, * even if the key requires more bytes than the original value.

The HKDF is divided into two parts, one the extractor and the other the expander. This is the puller:

prk = hmac_sha256(salt, ikm)

The idea here is to include salt and ikm . It assumes that salt is distinguishable from a uniformly random data, since ikm may be, but need not be.

Its result, prk , is a uniformly random data, assuming hmac_sha256 is a safe PRF, or that at least SHA256 compression is a PRF.

>

After that we have the expander, which consumes prk , it is in:

for i in range(ceil(length / hash_len)):

    t = hmac_sha256(prk, t + info + bytes([1+i]))

Note that prk is used as the key in this step. That is, the key generated by the extractor is used in the expander. The expander will create n required bytes, so there is range to repeat the process until it reaches the required number of bytes.

Formally this process is described as:

K(1) = HMAC(PRK, CTXinfo || 0),
K(i + 1) = HMAC(PRK, K(i) || CTXinfo || i), 1 ≤ i < t,

The CTXinfo is additional information, can be omitted. So basically the input of the HMAC is: the previous result (if i> 1) concatenated with the information added and concatenated with the i,% being a single byte, sequential.

In the case of this implementation, as defined by i , there will be no difference between the first or last execution.

Finally, t = b"" will only cut the output, since the hash is fixed size (in the case of SHA-256), so if you want non-multiples of 256, for example, you will not be able to get truncated.

    
13.06.2018 / 01:31
0

If I'm correct, this is how it works:

# Comentários na linha de cima à linha comentada.

import hashlib
import hmac
from math import ceil

# As palavras vão ter 32 bytes.
hash_len = 32

# Define um método que aplica SHA256 com a key e os data informados.
def hmac_sha256(key, data):
    return hmac.new(key, data, hashlib.sha256).digest()

# Cria um HMAC do tamanho length, com a chave ikm, o sal salt e uma informação, também usada para a criação do HMAC, info.
def hkdf(length, ikm, salt=b"", info=b""):

    # Gera uma chave preliminar com o salt e o ikm informados.
    prk = hmac_sha256(salt, ikm)

    # Declara um espaçador t.
    t = b""

    # Declara o HMAC final okm.
    okm = b""

    # Laço para gerar o HMAC; itera-se sobre um vetor [0..ceil(length / 32)]
    for i in range(ceil(length / hash_len)):
        # O espaçador guarda o resultado do algoritmo de hashing
        # a cada iteração, usando como base para tal a si próprio,
        # a info e um vetor de zeros de tamanho variável, apenas
        # como preenchedor (para que t não fique viciado).
        t = hmac_sha256(prk, t + info + bytes([1+i]))

        # Concatena t em okm
        okm += t

    # Recorta okm do tamanho length informado.
    return okm[:length]
As the HMAC accompanies the signed message at any time of the message exchange, the fact that HMAC is truncated is not significant, since it can be checked at any time if the message recipient has the same length , ikm , salt and info passed as parameters of hkdf() , which should also be known by the receiving side.

    
10.06.2018 / 21:21