Mapa da aula
Aula 16 publicada. Mapa, exemplo, EX046.
flowchart TD
N0["16.1 Hash resistente em memória"]
N1["Laboratório — scrypt com um vetor de teste"]
N2["16.2 Ler a execução do scrypt"]
N3["16.3 Planejar a migração"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4
N4 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX046"]
Desenho lógico
flowchart LR
N0["16.1 Hash resistente em memória"]
N1["Laboratório — scrypt com um vetor de teste"]
N2["16.2 Ler a execução do scrypt"]
N3["16.3 Planejar a migração"]
N4["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> Q["EX046"]
[16.1 Hash resistente em memória]
|
v
[Laboratório — scrypt com um vetor de teste]
|
v
[16.2 Ler a execução do scrypt]
|
v
[16.3 Planejar a migração]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX046]
Objetivos de aprendizagem
Você vai (1) armazenar senhas com hash resistente em memória; (2) verificar uma chamada de implementação contra um vetor de teste publicado; (3) planejar a migração de um armazenamento de senhas fraco.
16.1 Hash resistente em memória
As contas dos cidadãos no portal de licenças precisam de um armazenamento seguro de senhas. Rosa aprende que os hashes rápidos permitem que os atacantes testem bilhões de palpites por segundo depois de roubar um banco de dados, enquanto as funções resistentes em memória tornam cada palpite caro em memória além de tempo, desacelerando o hardware especializado. O Argon2id, da RFC 9106, é a escolha preferida; o scrypt, da RFC 7914, é uma alternativa consolidada disponível no hashlib do Python. O código de produção usa uma biblioteca avaliada de hash de senhas, com parâmetros ajustados; o laboratório usa o hashlib.scrypt para mostrar a ideia.
Laboratório — scrypt com um vetor de teste
"""Check hashlib.scrypt against an RFC 7914 test vector, then store a synthetic password."""
import hashlib, hmac
WANT = ("fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640")
def main():
got = hashlib.scrypt(b"password", salt=b"NaCl", n=1024, r=8, p=16, dklen=64).hex()
print("RFC 7914 vector matches:", got == WANT)
salt = bytes.fromhex("5e" * 16) # fixed demo salt for repeatable output
stored = hashlib.scrypt(b"Permit-Desk-2026!", salt=salt, n=2**14, r=8, p=1, dklen=32)
ok = hmac.compare_digest(stored, hashlib.scrypt(b"Permit-Desk-2026!", salt=salt, n=2**14, r=8, p=1, dklen=32))
print("stored:", stored.hex()[:24], "... verify:", ok)
if __name__ == "__main__":
main()
Execute com python3 lab_scrypt.py. Saída verificada:
RFC 7914 vector matches: True
stored: ddb1b7d5e7566125ab501de6 ... verify: True
16.2 Ler a execução do scrypt
O laboratório primeiro confere o hashlib.scrypt contra um vetor de teste publicado na RFC 7914, com a senha "password", o salt "NaCl", N 1024, r 8 e p 16; a saída de 64 bytes coincide. Coincidir com o vetor confirma que a função é chamada com os significados corretos dos parâmetros. Em seguida, ele armazena uma senha sintética de um funcionário com um salt e N igual a 2^14, e a verificação com compare_digest retorna True. O salt fixo serve apenas para tornar a saída repetível; os salts reais são aleatórios por usuário. Rosa registra os parâmetros ao lado do hash armazenado, para que possam ser elevados mais tarde.
16.3 Planejar a migração
O portal hoje armazena as senhas com SHA-256 com salt, que é rápido demais. Rosa planeja uma migração: quando um cidadão faz login com sucesso, o portal verifica contra o hash antigo e armazena imediatamente um novo hash resistente em memória; as contas que nunca fazem login são envolvidas aplicando a nova função sobre o hash antigo, de modo que nenhum hash fraco permaneça armazenado. Depois de um período definido, as contas sem uso são convidadas a redefinir a senha. O plano evita forçar milhões de redefinições de senha de uma só vez. Ela estima a carga do servidor com o novo hash nos horários de pico de login antes de programar a mudança.
Exemplo resolvido
Rosa confirma o hashlib.scrypt contra a RFC 7914, armazena uma senha sintética e planeja a migração do SHA-256 com salt por novo hash no login mais envolvimento.
Caso sintético. O portal e as senhas são inventados; a RFC 7914 e a RFC 9106 são reais.
Erros e limites
Os parâmetros resistentes em memória precisam ser ajustados à capacidade do servidor. O envolvimento dos hashes antigos precisa ser feito com cuidado para evitar bloqueios de contas.
Exercícios
-
EX046 — Por que resistente em memória. Por que as funções resistentes em memória são melhores para senhas do que os hashes rápidos?
Mostrar critérios de avaliação
Rubrica: 3 = cada palpite custa memória e tempo, desacelerando o hardware especializado;; 2 = mais lentas;; 1 = iguais;; 0 = nenhuma. -
EX047 — Propósito do vetor. O que coincidir com o vetor da RFC 7914 confirma?
Mostrar critérios de avaliação
Rubrica: 3 = a função é chamada com os significados corretos dos parâmetros;; 2 = uso correto;; 1 = segurança;; 0 = nenhuma. -
EX048 — Método de migração. Como as contas que nunca fazem login ficam protegidas durante a migração?
Mostrar critérios de avaliação
Rubrica: 3 = o hash antigo é envolvido pela nova função resistente em memória;; 2 = envolvimento;; 1 = ignoradas;; 0 = nenhuma.
Síntese
O hash resistente em memória, verificado contra vetores de teste e introduzido por uma migração cuidadosa, protege as senhas dos cidadãos.