File size: 6,803 Bytes
9b0e9b6
 
f45d790
 
 
9b0e9b6
 
 
 
 
f45d790
 
9b0e9b6
 
2ad4a31
9b0e9b6
f45d790
 
 
 
 
9b0e9b6
 
f45d790
9b0e9b6
f45d790
 
 
 
 
 
 
 
9b0e9b6
 
f45d790
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9b0e9b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f45d790
 
 
9b0e9b6
 
 
 
 
 
 
f45d790
 
9b0e9b6
 
 
 
f45d790
 
 
 
 
9b0e9b6
 
 
f45d790
 
 
9b0e9b6
 
 
 
 
 
f45d790
9b0e9b6
 
 
 
 
 
 
 
 
 
 
 
 
 
f45d790
 
 
9b0e9b6
 
 
f45d790
 
 
 
 
 
9b0e9b6
 
 
 
 
 
 
 
 
f45d790
 
 
 
 
9b0e9b6
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/env python3
"""
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 registrado
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)  # Parse JSON

        # Serialização canônica: sort_keys=True, sem espaços
        # Isso garante que o mesmo conteúdo sempre gera o mesmo hash
        canonical_json = json.dumps(data, sort_keys=True, separators=(',', ':'))

        # Hash do JSON canônico
        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':
            # Fingerprint do modelo - verificação diferente
            continue

        if not isinstance(components, dict):
            continue

        for comp_name, comp_hash in components.items():
            oids_totais += 1

            # Verifica se é um hash SHA-256 válido (64 chars hex)
            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}")

        # Verifica OIDs individuais
        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}")

    # Calcula hash usando serialização canônica
    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=(',',':'))")

    # Compara hashes
    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.")

        # Mostra componentes
        verificar_componentes(arquivo)

        # Verifica assinatura GPG (se existir)
        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)

        # Debug: mostra primeiros chars do JSON canônico
        print(f"\nJSON canônico (primeiros 200 chars):")
        print(f"{canonical_json[:200]}...")

        print("\n" + "="*80)
        sys.exit(1)

if __name__ == "__main__":
    main()