|
|
|
|
|
""" |
|
|
Script de Verificação CORRETO do Hash do Sistema VICK AI |
|
|
Usa serialização canônica JSON (determinística) |
|
|
Versão: 2.1 |
|
|
""" |
|
|
|
|
|
import hashlib |
|
|
import json |
|
|
import sys |
|
|
import os |
|
|
from pathlib import Path |
|
|
|
|
|
|
|
|
HASH_OFICIAL = "2ed9c8531958fa878637f852412e9490b53b33afe0ef6bc4d12c33c68563db05" |
|
|
|
|
|
def calcular_hash_canonico(arquivo_json): |
|
|
""" |
|
|
Calcula hash SHA-256 usando serialização canônica do JSON |
|
|
Garante determinismo mesmo com formatação diferente |
|
|
""" |
|
|
try: |
|
|
with open(arquivo_json, 'r', encoding='utf-8') as f: |
|
|
data = json.load(f) |
|
|
|
|
|
|
|
|
|
|
|
canonical_json = json.dumps(data, sort_keys=True, separators=(',', ':')) |
|
|
|
|
|
|
|
|
hash_calculado = hashlib.sha256(canonical_json.encode('utf-8')).hexdigest() |
|
|
|
|
|
return hash_calculado, canonical_json |
|
|
except Exception as e: |
|
|
print(f"❌ Erro ao calcular hash: {e}") |
|
|
return None, None |
|
|
|
|
|
def verificar_oids_individuais(data): |
|
|
""" |
|
|
Verifica OIDs (Object IDs) de cada componente individual |
|
|
""" |
|
|
print("\n🔍 Verificando OIDs individuais dos componentes...") |
|
|
|
|
|
component_details = data.get('component_details', {}) |
|
|
oids_verificados = 0 |
|
|
oids_totais = 0 |
|
|
|
|
|
for category, components in component_details.items(): |
|
|
if category == '00_llm_fingerprint': |
|
|
|
|
|
continue |
|
|
|
|
|
if not isinstance(components, dict): |
|
|
continue |
|
|
|
|
|
for comp_name, comp_hash in components.items(): |
|
|
oids_totais += 1 |
|
|
|
|
|
|
|
|
if len(comp_hash) == 64 and all(c in '0123456789abcdef' for c in comp_hash): |
|
|
oids_verificados += 1 |
|
|
else: |
|
|
print(f" ⚠️ {comp_name}: hash inválido") |
|
|
|
|
|
print(f" ✓ {oids_verificados}/{oids_totais} OIDs válidos") |
|
|
return oids_verificados == oids_totais |
|
|
|
|
|
def verificar_assinatura_gpg(arquivo): |
|
|
""" |
|
|
Verifica assinatura GPG do manifest (se existir) |
|
|
""" |
|
|
sig_file = f"{arquivo}.sig" |
|
|
|
|
|
if not os.path.exists(sig_file): |
|
|
print("\n⚠️ Assinatura GPG não encontrada") |
|
|
print(f" Procurando por: {sig_file}") |
|
|
print(f" Recomendação: Assinar o manifest com GPG") |
|
|
return None |
|
|
|
|
|
print(f"\n🔐 Verificando assinatura GPG...") |
|
|
|
|
|
try: |
|
|
import subprocess |
|
|
result = subprocess.run( |
|
|
['gpg', '--verify', sig_file, arquivo], |
|
|
capture_output=True, |
|
|
text=True |
|
|
) |
|
|
|
|
|
if result.returncode == 0: |
|
|
print(f" ✓ Assinatura GPG válida!") |
|
|
print(f" {result.stderr.split('Good signature')[1].split('\\n')[0] if 'Good signature' in result.stderr else ''}") |
|
|
return True |
|
|
else: |
|
|
print(f" ✗ Assinatura GPG inválida") |
|
|
print(f" {result.stderr}") |
|
|
return False |
|
|
except FileNotFoundError: |
|
|
print(f" ⚠️ GPG não instalado no sistema") |
|
|
return None |
|
|
except Exception as e: |
|
|
print(f" ✗ Erro ao verificar assinatura: {e}") |
|
|
return None |
|
|
|
|
|
def verificar_componentes(arquivo_json): |
|
|
"""Verifica componentes do fingerprint""" |
|
|
try: |
|
|
with open(arquivo_json, 'r', encoding='utf-8') as f: |
|
|
data = json.load(f) |
|
|
|
|
|
print("\n📊 Informações do Certificado:") |
|
|
print(f" Sistema: {data.get('system')}") |
|
|
print(f" Versão: {data.get('version')}") |
|
|
print(f" Criador: {data.get('creator')}") |
|
|
print(f" Timestamp: {data.get('timestamp')}") |
|
|
|
|
|
total_components = data.get('metadata', {}).get('total_components', 0) |
|
|
print(f"\n📁 Total de Componentes: {total_components}") |
|
|
|
|
|
print("\n🧬 Fingerprint do Modelo LLM:") |
|
|
llm_fp = data.get('component_details', {}).get('00_llm_fingerprint', {}) |
|
|
for key, value in llm_fp.items(): |
|
|
print(f" • {key}: {value}") |
|
|
|
|
|
|
|
|
verificar_oids_individuais(data) |
|
|
|
|
|
return True |
|
|
except Exception as e: |
|
|
print(f"❌ Erro ao ler componentes: {e}") |
|
|
return False |
|
|
|
|
|
def main(): |
|
|
print("="*80) |
|
|
print("🔐 VERIFICADOR DE HASH CORRETO - SISTEMA VICK AI v2.1") |
|
|
print(" Usa serialização canônica JSON (determinística)") |
|
|
print("="*80) |
|
|
|
|
|
arquivo = "vick_fingerprint.json" |
|
|
|
|
|
if not os.path.exists(arquivo): |
|
|
print(f"\n❌ Arquivo não encontrado: {arquivo}") |
|
|
print(f" Execute este script no diretório que contém {arquivo}") |
|
|
sys.exit(1) |
|
|
|
|
|
print(f"\n📄 Arquivo: {arquivo}") |
|
|
print(f"🎯 Hash Oficial: {HASH_OFICIAL}") |
|
|
|
|
|
|
|
|
print(f"\n⏳ Calculando hash com serialização canônica...") |
|
|
hash_calculado, canonical_json = calcular_hash_canonico(arquivo) |
|
|
|
|
|
if not hash_calculado: |
|
|
print("\n❌ FALHA NA VERIFICAÇÃO") |
|
|
sys.exit(1) |
|
|
|
|
|
print(f"✓ Hash Calculado: {hash_calculado}") |
|
|
print(f" (usando JSON canônico: sort_keys=True, separators=(',',':'))") |
|
|
|
|
|
|
|
|
print(f"\n🔍 Comparando hashes...") |
|
|
|
|
|
if hash_calculado == HASH_OFICIAL: |
|
|
print("\n" + "="*80) |
|
|
print("✅ CERTIFICADO AUTÊNTICO!") |
|
|
print("="*80) |
|
|
print("\nO hash calculado corresponde ao hash oficial registrado.") |
|
|
print("Este certificado é genuíno e não foi alterado desde o registro.") |
|
|
|
|
|
|
|
|
verificar_componentes(arquivo) |
|
|
|
|
|
|
|
|
verificar_assinatura_gpg(arquivo) |
|
|
|
|
|
print("\n" + "="*80) |
|
|
print("✓ Verificação concluída com sucesso") |
|
|
print("="*80) |
|
|
|
|
|
print("\n💡 NOTA IMPORTANTE:") |
|
|
print(" Este script usa serialização canônica (determinística).") |
|
|
print(" O hash é calculado sobre JSON com sort_keys=True,") |
|
|
print(" garantindo que formatação diferente não afete o resultado.") |
|
|
|
|
|
sys.exit(0) |
|
|
else: |
|
|
print("\n" + "="*80) |
|
|
print("❌ CERTIFICADO INVÁLIDO!") |
|
|
print("="*80) |
|
|
print("\n⚠️ ATENÇÃO: O hash não corresponde ao hash oficial.") |
|
|
print("Este arquivo pode ter sido modificado ou corrompido.") |
|
|
print("\nHash esperado:", HASH_OFICIAL) |
|
|
print("Hash calculado:", hash_calculado) |
|
|
|
|
|
|
|
|
print(f"\nJSON canônico (primeiros 200 chars):") |
|
|
print(f"{canonical_json[:200]}...") |
|
|
|
|
|
print("\n" + "="*80) |
|
|
sys.exit(1) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
main() |
|
|
|