Capítulo 24 — Criptografia e serviços de confiança: métodos I
Mapa da aula
Aula 24 publicada. Mapa, exemplo, EX070.
flowchart TD
N0["24.1 Por que derivar chaves"]
N1["Laboratório — HKDF contra a RFC 5869"]
N2["24.2 Ler a execução do HKDF"]
N3["24.3 Contexto e separação"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX070"]
Desenho lógico
flowchart LR
N0["24.1 Por que derivar chaves"]
N1["Laboratório — HKDF contra a RFC 5869"]
N2["24.2 Ler a execução do HKDF"]
N3["24.3 Contexto e separação"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX070"]
[24.1 Por que derivar chaves]
|
v
[Laboratório — HKDF contra a RFC 5869]
|
v
[24.2 Ler a execução do HKDF]
|
v
[24.3 Contexto e separação]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX070]
Objetivos de aprendizagem
Você vai (1) derivar muitas chaves de uma chave mestra com o HKDF; (2) verificar uma implementação contra vetores de teste publicados; (3) separar as chaves por finalidade com informações de contexto.
24.1 Por que derivar chaves
A Ridgeway precisa de chaves separadas para cada medidor e para cada finalidade. Armazenar 50.000 chaves aleatórias é possível, mas derivá-las de uma chave mestra no serviço de chaves simplifica o backup e o provisionamento. O HKDF, especificado na RFC 5869, faz isso em duas etapas: a extração (extract) concentra a entropia do material de chave de entrada numa chave pseudoaleatória usando HMAC com um salt, e a expansão (expand) produz quantos bytes de saída forem necessários, vinculados a uma string info que descreve a finalidade. Strings info diferentes geram chaves independentes, de modo que uma chave de telemetria não pode ser confundida com uma chave de firmware.
Laboratório — HKDF contra a RFC 5869
"""Check HKDF-SHA256 against RFC 5869 test case 1 (teaching only: use a vetted library in production)."""
import hmac, hashlib
def hkdf(ikm, salt, info, length):
prk = hmac.new(salt, ikm, hashlib.sha256).digest() # extract
okm, t, i = b"", b"", 1
while len(okm) < length: # expand
t = hmac.new(prk, t + info + bytes([i]), hashlib.sha256).digest(); okm += t; i += 1
return prk, okm[:length]
def main():
prk, okm = hkdf(bytes([0x0b]) * 22, bytes(range(13)), bytes(range(0xf0, 0xfa)), 42)
want = "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
print("PRK", prk.hex()[:32], "...")
print("OKM matches RFC 5869 A.1:", okm.hex() == want)
a = hkdf(b"utility-master-demo", b"salt", b"telemetry-tls", 16)[1].hex()
b = hkdf(b"utility-master-demo", b"salt", b"firmware-sign", 16)[1].hex()
print("different info, different keys:", a != b)
if __name__ == "__main__":
main()
Execute com python3 lab_hkdf.py. Saída verificada:
PRK 077709362c2e32df0ddc3f0dc47bba63 ...
OKM matches RFC 5869 A.1: True
different info, different keys: True
24.2 Ler a execução do HKDF
O laboratório implementa o HKDF com hmac apenas para tornar visíveis as duas etapas e o confere contra o caso de teste A.1 da RFC 5869: a saída de 42 bytes coincide exatamente. Em seguida, ele deriva duas chaves da mesma chave mestra de demonstração com strings info diferentes, telemetry-tls e firmware-sign, e confirma que elas diferem. Aiyana escreve ao lado do código que o serviço de chaves de produção da Ridgeway usa o HKDF de uma biblioteca avaliada; o objetivo do exercício é entender e verificar o comportamento, e não implantar uma versão escrita à mão. Um vetor de teste que coincide prova o uso correto, não a segurança contra canais laterais.
24.3 Contexto e separação
Aiyana projeta as strings info com cuidado: elas incluem a finalidade, o identificador do medidor e a versão da chave, como "ridgeway/reading-hmac/M-0417/v3". Incluir a versão permite a rotação derivando uma nova chave sem mudar a chave mestra. Incluir o identificador do medidor torna única a chave de cada medidor. Ela alerta contra reutilizar uma chave derivada para duas finalidades, como gerar tags de leituras e cifrar a configuração, porque uma fraqueza ou um uso indevido num uso poderia comprometer o outro. A separação de chaves é um hábito de projeto barato e poderoso. Ela documenta o formato dos rótulos para que todas as equipes derivem as chaves de forma idêntica.
Exemplo resolvido
Aiyana verifica o comportamento do HKDF contra o caso A.1 da RFC 5869 e depois especifica strings info que codificam a finalidade, o identificador do medidor e a versão, para chaves por medidor e rotacionáveis.
Caso sintético. A chave mestra e os rótulos são inventados; a RFC 5869 e seu vetor de teste são reais.
Erros e limites
O HKDF não acrescenta entropia; uma chave mestra fraca gera chaves derivadas fracas. Versões escritas à mão servem apenas para aprender.
Exercícios
-
EX070 — Extração e expansão. O que fazem as duas etapas do HKDF? Rubrica: 3 = a extração gera uma chave pseudoaleatória a partir do material de entrada com um salt; a expansão produz bytes vinculados à info;; 2 = uma etapa;; 1 = cifração;; 0 = nenhuma.
-
EX071 — Resultado do vetor de teste. O que o laboratório imprimiu na verificação da RFC 5869? Rubrica: 3 = OKM matches RFC 5869 A.1: True;; 2 = True;; 1 = False;; 0 = nenhuma.
-
EX072 — Projeto da string info. O que Aiyana coloca nas strings info, e por que incluir a versão? Rubrica: 3 = finalidade, identificador do medidor, versão; a versão permite a rotação sem mudar a chave mestra;; 2 = parcial;; 1 = aleatório;; 0 = nenhuma.
Síntese
O HKDF deriva muitas chaves separadas e rotacionáveis a partir de uma chave mestra bem protegida, e os vetores de teste confirmam o uso correto.
Continue estudando — aula 24 (capítulo 24 de 50)
← Capítulo 23 · Índice das aulas · Capítulo 25 →
Continue para a próxima aula já escrita.