O algoritmo (CHAVE_INTERNA + funcoes gerarReativacao/gerarInstalacao) ficava 100% legivel no codigo-fonte da pagina — qualquer pessoa com acesso ao painel conseguia abrir o DevTools e extrair a logica pra gerar chaves de licenca fora do sistema. Move tudo pra app/gerador_chave.py (roda so no servidor) e expoe via POST /gerador-chave/gerar (autenticado, protegido por CSRF). A pagina agora so manda os dados do formulario e mostra o resultado que volta do backend. Algoritmo verificado byte-a-byte contra os 3 exemplos reais conhecidos (cliente 000001, ALUGUEL). Bonus: o byte inicial agora usa secrets.randbelow (CSPRNG) em vez de Math.random() do JS. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.6 KiB
Python
42 lines
1.6 KiB
Python
from app.gerador_chave import gerar_instalacao, gerar_reativacao
|
|
|
|
|
|
def test_gerar_instalacao_bate_com_exemplo_real_byte_dc():
|
|
assert gerar_instalacao("000001", "ALUGUEL", byte_inicial=0xDC) == "DC45092C"
|
|
|
|
|
|
def test_gerar_instalacao_bate_com_exemplo_real_byte_2e():
|
|
assert gerar_instalacao("000001", "ALUGUEL", byte_inicial=0x2E) == "2E35083D"
|
|
|
|
|
|
def test_gerar_instalacao_bate_com_exemplo_real_byte_3d():
|
|
assert gerar_instalacao("000001", "ALUGUEL", byte_inicial=0x3D) == "3D25090C"
|
|
|
|
|
|
def test_gerar_instalacao_compra_usa_modalidade_00():
|
|
# Mesmo byte inicial, modalidade diferente -> cifrado diferente do ALUGUEL.
|
|
aluguel = gerar_instalacao("000001", "ALUGUEL", byte_inicial=0xDC)
|
|
compra = gerar_instalacao("000001", "COMPRA", byte_inicial=0xDC)
|
|
assert aluguel != compra
|
|
assert compra.startswith("DC") # byte inicial some no começo, sem cifrar
|
|
|
|
|
|
def test_gerar_instalacao_sem_byte_inicial_gera_aleatorio_valido():
|
|
chave = gerar_instalacao("000001", "ALUGUEL")
|
|
assert len(chave) == 8
|
|
assert chave[3:5].isdigit() # valor_cliente embutido no meio
|
|
|
|
|
|
def test_gerar_reativacao_e_deterministico_com_byte_fixo():
|
|
chave1 = gerar_reativacao("000123", 8, 2026, byte_inicial=0x10)
|
|
chave2 = gerar_reativacao("000123", 8, 2026, byte_inicial=0x10)
|
|
assert chave1 == chave2
|
|
assert len(chave1) == 22 # 11 bytes (1 aleatorio + 10 do texto) em hex
|
|
|
|
|
|
def test_gerar_reativacao_sem_byte_inicial_varia():
|
|
# Estatisticamente, gerar várias vezes sem byte fixo não deve sempre
|
|
# bater igual (chance de colisão é 1/256).
|
|
chaves = {gerar_reativacao("000123", 8, 2026) for _ in range(20)}
|
|
assert len(chaves) > 1
|