Pular para o conteúdo principal

Segurança

O que protege o quê na plataforma, onde fica cada segredo e o que o operador precisa guardar.

A premissa fundamental e sua única exceção​

A chave privada de um Certificado de Estação de Trabalho nunca sai da estação de trabalho. O Workstation Service é o único caminho até os certificados de uma máquina, a chave só vê um hash, e a assinatura com um certificado A3 acontece no hardware que o guarda. Nada no Servidor consegue assinar com um Certificado de Estação de Trabalho, e nada no produto exporta um.

O Cofre de Certificados é a exceção deliberada, desligada por padrão. Com Vault:Enabled=true, um Administrador pode importar um certificado A1, com chave e tudo, e o Servidor assina com ele. Isso troca custódia por conveniência: uma chave armazenada no próprio repositório da plataforma, em vez de em um cartão que não consegue entregá-la. Qual custódia um certificado usa é assunto do operador e do auditor; a aplicação cliente nunca é informada.

Tratamento do PIN​

O PIN é o que autentica o titular perante o token dele, para que uma assinatura possa ser feita. Desde o Servidor 1.13.0 e o Workstation 1.5.0 (protocolo 5 das estações de trabalho), o PIN que uma aplicação cliente envia não passa do Servidor. Quatro regras o regem:

  • O PIN é digitado localmente. O titular o digita no Tray App da máquina em que o token está conectado, somente na sessão de console. O Workstation Service o guarda, criptografado, no Cache de PIN, indexado por certificado, com um TTL de inatividade deslizante (8 h por padrão). Para um Certificado A1, a máquina guarda em vez disso um verificador de um PIN do Certificado A1 (abaixo).

  • Uma correspondência é uma prova que o Servidor confere. Em POST /v1/sessions, o Servidor desafia todas as máquinas candidatas ao mesmo tempo com um nonce aleatório novo. Cada uma responde com uma Prova de PIN, um HMAC sobre o nonce cuja chave é o PIN que ela tem em cache (ou o verificador do PIN do Certificado A1), ou informa que não tem com o que provar. O Servidor calcula a prova esperada a partir do PIN que o cliente enviou e decide. A máquina a que a sessão se vincula é avisada disso, e uma máquina cujo pedido no Tray App foi respondido recebe o veredito sobre essa entrada; é tudo o que uma máquina fica sabendo. Uma máquina nunca recebe o PIN, e um valor errado vindo da rede nunca chega ao token nem consome o contador de tentativas dele. Só PINs digitados pelo titular chegam ao hardware. Um Servidor a partir da 1.15.0 recusa no handshake uma máquina abaixo do protocolo 5.

  • Três limites restringem tentativas de adivinhação.

    • O bloqueio por CPF. O Servidor bloqueia a criação de sessões para um CPF após Sessions:MaxPinFailures (5) falhas dentro de Sessions:PinFailureWindow (15 min), contadas em todas as chaves de API e respondidas com 429 TOO_MANY_PIN_ATTEMPTS. Uma requisição conta no máximo uma falha. Uma criação bem-sucedida não as zera: elas saem da janela com o tempo.
    • Os limites de provas com falha. Toda Prova de PIN que uma estação de trabalho dá para um CPF e que não confere conta contra essa máquina e esse CPF, mesmo que outra candidata tenha correspondido, com os mesmos dois valores. Quando uma máquina esgota o seu limite, ela não recebe desafio nem pedido de PIN para esse CPF até as falhas saírem da janela; o Servidor registra um Warning e grava pin.proof-budget-spent. O Cofre de Certificados tem um limite por CPF nas mesmas condições: cada senha que ele tenta e que não abre nada conta uma vez por requisição. Assim, quem tem uma chave de API e uma máquina admitida só consegue testar um punhado de palpites por titular por janela, seja pela máquina, seja pelo cofre. O limite é cobrado da máquina que deu a prova e de nenhuma outra, mas a própria máquina do titular, se guarda vários certificados dele, gasta uma prova com falha por certificado a cada PIN errado, então pode ser deixada de lado antes de o bloqueio disparar. Uma linha pin.proof-budget-spent, portanto, não prova que houve adivinhação: leia-a junto com as linhas pin.compared do CPF. Configuração mostra os três limites lado a lado.
    • O limite da própria estação de trabalho. Ela recusa entradas para um certificado após Tray:MaxConsecutivePinFailures (3) rejeições seguidas do token (ou PINs do Certificado A1 errados), durante Tray:PinFailureCooldown (5 min).

    Nenhum deles torna impossível o bloqueio do hardware: o titular ainda pode bloquear o próprio token digitando errado.

  • PINs e Provas de PIN nunca aparecem na Trilha de Auditoria, no log do Servidor nem no log do Workstation Service. Quem tem o nonce consegue quebrar uma prova por força bruta offline, então ela fica fora de todos os logs, como o PIN. O Cache de PIN fica só em memória por padrão; PinCache:SurviveRestart o persiste com DPAPI no escopo da máquina, em um arquivo acessível apenas a SYSTEM e aos Administradores, um desvio documentado que o administrador escolhe ativar.

O bloqueio e os limites são indexados pelo CPF do titular, qualquer que seja a Empresa que a sessão indique: o e-CPF e os e-CNPJs de um titular costumam compartilhar um PIN, então um palpite para um é um palpite para os outros.

Para um Certificado do Cofre, o pin que o cliente envia é a senha que abre o arquivo do certificado. O Servidor a usa para abrir a chave na criação da sessão, a mantém em memória somente para aquela sessão e nunca a grava. Desativar a sessão, ou reiniciar o Servidor, a descarta.

PIN por transação​

Por padrão, uma Sessão de Assinatura, depois de criada, autoriza sozinha todas as assinaturas feitas nela até terminar. Um Administrador pode passar uma Aplicação Cliente para o PIN por transação, e então toda chamada de assinatura nas sessões que ela cria precisa do PIN do titular só para aquela chamada:

  • Numa estação de trabalho, o titular autoriza cada chamada no Tray App, somente na sessão de console, depois de ver o nome da Aplicação Cliente e o que a chamada assina (os nomes dos documentos, ou o número de hashes). O token confere o PIN ou, num A1, o verificador do PIN do Certificado A1 o confere. O Service guarda o PIN aceito em memória, sob Data Protection, só para as assinaturas daquela chamada, e o apaga quando a chamada termina, os usos dele se esgotam, o tempo dele acaba, o token o recusa ou a conexão com o Servidor cai. Ele nunca é lido do Cache de PIN nem gravado nele, então não consegue estender a assinatura sem supervisão para as sessões de nenhuma outra aplicação. Uma assinatura que não indica uma autorização aberta é recusada. O PIN nunca passa pelo canal das estações de trabalho.
  • No Cofre de Certificados, onde não há a quem mostrar uma solicitação, o cliente envia a senha a cada chamada. O Servidor a confere uma vez por chamada, sob o mesmo bloqueio por CPF e o mesmo limite de provas com falha do cofre que valem na criação da sessão, usa-a nas assinaturas daquela chamada e a descarta; nada é guardado entre uma chamada e outra.
  • Uma máquina mantém no máximo Signing:MaxPendingAuthorizations (2) chamadas aguardando o titular, então um cliente com um sessionId não consegue enfileirar solicitações sem limite nem ocupar o throttle global com chamadas em espera.

Isso não torna seguro o vazamento de uma sessão: um sessionId continua abrindo a sessão para quem o tiver, mas, nesse modo, nada é assinado sem o PIN do titular para aquela chamada.

PIN dispensado na criação​

Desde o Servidor 1.18.0, um Administrador também pode configurar uma aplicação com PIN por transação para criar as sessões dela sem o PIN, de modo que o titular digite o PIN no Tray App a cada chamada e o integrador nunca o manipule. A opção só é oferecida enquanto o PIN por transação está ligado, desligar o PIN por transação a desliga junto, e ligá-la pede confirmação antes, dizendo o que ela aceita:

  • Uma chave dessa aplicação pode criar uma sessão para qualquer CPF que tenha um certificado na plataforma, ler esse certificado e substituir a sessão ativa desse CPF, sem o PIN. O certificado (nome, endereço de e-mail, cadeia) é material público, mas substituir uma sessão pode encerrar a sessão de outro integrador para aquele CPF, repetidamente. A chave não consegue assinar: toda chamada de assinatura numa sessão assim continua precisando do titular, no Tray App ou como o pin da chamada.
  • Nada é comprovado na criação. A sessão só se vincula quando exatamente um certificado poderia atendê-la, sem Prova de PIN, sem pedido de PIN e sem abrir o cofre, e nada conta para o bloqueio por CPF nem para nenhum limite de provas com falha. Um pin enviado é comprovado exatamente como antes; o bloqueio continua recusando um CPF bloqueado, com ou sem ele.
  • Uma linha de certificado que uma máquina admitida anunciou sem ter o certificado pode se vincular quando é a única candidata, por exemplo enquanto a máquina do próprio titular está offline. Essa máquina passa a receber as chamadas de assinatura da sessão e fica sabendo o que a aplicação pede para assinar. Ela não fica sabendo nenhum PIN, porque nenhum é enviado, e não consegue responder com uma assinatura que o certificado confirme: o serviço de assinatura confere a assinatura de um documento contra o certificado, e uma resposta da Assinatura de hash falha em quem a verificar.

O risco fica limitado às aplicações que um Administrador configurou assim. A Trilha de Auditoria distingue os dois tipos de criação: session.created traz pin, "proven" ou "none", e indica a máquina à qual a sessão se vinculou, e a opção grava admin.application-session-pin-waived e admin.application-session-pin-required.

Assinatura de hash​

A Assinatura de hash (POST /v1/signatures/hashes) entrega à chave do titular hashes que a própria Aplicação Cliente escolheu. Um hash não traz nada que diga de que ele é o hash, então nada na plataforma consegue inspecionar o que está sendo assinado: um e-CPF ICP-Brasil é também o login TLS do titular em serviços como o gov.br, e o hash de um handshake TLS retransmitido é exatamente um hash assim. É por isso que ela fica desligada para toda Aplicação Cliente até que um Administrador a conceda, por aplicação e nunca por chave, e que a concessão é verificada antes mesmo de a sessão ser consultada. Conceda-a só a um integrador em quem você confie para montar as próprias estruturas assinadas, e leia as linhas hash-signing.* dele na Trilha de Auditoria, uma por hash.

O PIN do Certificado A1​

Um Certificado A1 no repositório de certificados da máquina não tem token nem PIN próprio. Ele só assina pelo TrustBridge depois que o titular define um PIN do Certificado A1 para ele no Tray App, na sessão de console, naquela máquina. O Workstation Service guarda um verificador PBKDF2 com salt, nunca o PIN, em um arquivo em C:\ProgramData\TrustBridge\ protegido como o do Cache de PIN. Trocá-lo exige o atual, e um PIN esquecido é recuperado removendo o certificado do repositório e instalando-o de novo. O verificador é a chave da Prova de PIN da máquina, então conferi-lo custa ao Servidor uma derivação de chave por máquina por requisição. Ele é apagado quando o certificado sai da máquina e por uma desinstalação completa, e uma atualização o mantém.

Quem consegue administrar o repositório de certificados de uma máquina, ou está no console dela antes de um PIN do Certificado A1 ser definido, controla quem pode assinar com aquele A1. O PIN do Certificado A1 decide quem pode assinar pelo TrustBridge; ele não protege a chave, que continua tão utilizável no repositório quanto antes.

O Protetor do Chaveiro​

Os dois chaveiros (key rings) do Servidor são linhas no banco de dados dele:

ChaveiroProtegeSe não puder ser lido
web-sessionsCookies do console administrativo, tokens antifalsificação (antiforgery), circuitos do BlazorTodos os administradores entram de novo, e nada mais
certificate-vaultA chave privada de cada Certificado do CofreO host para. Gerar uma chave nova deixaria órfão, silenciosamente, todo certificado já armazenado

Os dois são selados sob um único certificado X.509 com uma chave RSA que a plataforma não guarda: o Protetor do Chaveiro (Key Ring Protector), fornecido como KeyRingProtector:Certificate (PKCS#12 em base64). Todo Servidor precisa de um, com ou sem cofre, porque o chaveiro das sessões web também precisa dele. Quem consegue ler o protetor e o banco de dados consegue ler todos os Certificados do Cofre; portanto, o protetor é um segredo por si só, e o .env ou o app setting que o contém merece o mesmo cuidado que uma chave privada.

Faça backup do PKCS#12 permanentemente, em algum lugar que a plataforma não consiga acessar. Perdê-lo torna todos os Certificados do Cofre impossíveis de abrir por qualquer pessoa, inclusive por esta plataforma. Não há custódia de recuperação (escrow), de propósito. Uma referência ao Key Vault no Azure é um lugar conveniente para o Servidor em execução, e não um backup.

A rotação é aditiva. Um protetor novo sela chaves novas; ele nunca recriptografa o que já está armazenado. O protetor que sai passa para KeyRingProtector:RetiredCertificates:{n}:Certificate, e o PKCS#12 dele é guardado para sempre. Exclua um protetor aposentado e você terá destruído tudo o que foi selado sob ele, com todos os sintomas apontando para o banco de dados. O Servidor informa essa situação a cada inicialização: o thumbprint atual e a quantidade de protetores aposentados.

O Cofre de Certificados​

Ligar esse recurso traz três coisas:

  • A licença do Lacuna PKI SDK ganha uma segunda função. Toda implantação já tem uma, porque ela é a licença com que a frota inteira funciona (abaixo). Com o cofre ligado, o Servidor também valida o que guarda por meio do SDK, que não lê nada sem licença. Com a licença recusada ou vencida, todo Certificado do Cofre aparece como UNTRUSTED e toda importação é recusada, o que é informado uma vez na inicialização, numa linha Critical, e num banner em todas as páginas administrativas.
  • Um PKCS#12 precisa estar no formato PFX legado. A biblioteca com que a plataforma assina não lê uma chave protegida com pkcs5PBES2, que é o que openssl pkcs12 -export grava se não receber -legacy, e o que caminhos de exportação recentes do Windows também gravam. Um arquivo assim é recusado na importação, com a indicação de exportá-lo de novo:
    openssl pkcs12 -export -legacy -in holder.pem -inkey holder.key -out holder.pfx
  • O cofre pode ficar travado fechado quando o Servidor inicia antes de o banco de dados responder. Veja Operações.

A senha de importação é usada para provar que o arquivo abre e nunca é armazenada: nada consegue abrir um arquivo armazenado sem alguém presente, e é também por isso que nenhum processo automático consegue verificar se arquivos antigos estão no formato legado. Senhas erradas enviadas na criação de sessões gastam o limite de provas com falha do cofre para aquele CPF (Tratamento do PIN). Não há caminho de exportação nem de download. Um certificado sai do cofre ao ser excluído, o que destrói a chave e não pode ser desfeito, e a confirmação pede que o CPF seja digitado. Fora de uso impede que um certificado abra sessões e assine, mas o mantém.

Uma Sessão de Assinatura vinculada ao cofre não sobrevive a um reinício do Servidor, porque o segredo que abre o certificado fica só na memória. Isso é uma propriedade da custódia, não um defeito.

Chaves de API​

Uma chave de API autentica uma Aplicação Cliente em toda a superfície do contrato. Ela é emitida na tela Aplicações Cliente com um nome e uma validade opcional, exibida uma única vez e armazenada apenas como o SHA-256 dela. Todas as chaves aceitas de uma aplicação são equivalentes; a chave não restringe nada.

  • Revogue uma chave e a próxima requisição que a apresentar será recusada, permanentemente.
  • Desative uma aplicação e todas as chaves dela passam a ser recusadas imediatamente; ativá-la de novo as restaura.
  • Faça uma chave expirar no fim de um dia em UTC, ou apague a data para que ela volte a não ter validade.
  • Para fazer a rotação, emita uma chave nova ao lado da antiga, implante-a e então revogue a antiga.

Chaves ausentes, desconhecidas, revogadas, expiradas e de aplicações desativadas são todas recusadas da mesma forma, com 401 UNAUTHORIZED, então quem chama não descobre qual era o caso. Cada chave tem a própria trilha na Trilha de Auditoria, inclusive as chamadas recusadas.

Um sessionId e um signatureId são tokens de portador daquilo que identificam: qualquer chave aceita pode usar uma sessão ou buscar um documento cujo id ela tenha. Não entregue nenhum dos dois a quem não deveria tê-los.

A Assinatura de teste​

Uma Assinatura de teste pede uma chave de API, um CPF e o PIN dele (que pode ficar em branco quando a aplicação da chave cria as sessões dela sem o PIN), e faz uma assinatura real. O Servidor não tem chave própria para ela: a execução é feita como a Aplicação Cliente cuja chave foi digitada, então uma demonstração começa entregando uma chave a alguém, e quem a tiver pode usá-la diretamente contra o contrato. Emita uma chave dedicada para demonstrações e revogue-a depois.

A partir do Servidor 1.23.0, a página devolve todos os campos preenchidos na página que responde ao formulário, inclusive a chave e o PIN, para que Assinar de novo seja um único clique. Essa página de resposta é enviada com no-store, então não fica no cache do navegador, mas a chave e o PIN ficam nela enquanto a aba estiver aberta: uma demonstração num computador compartilhado termina com a aba fechada. O Servidor continua não registrando nenhum dos dois em log e esquece ambos assim que essa página é escrita. (Antes do 1.23.0, a página nunca devolvia nenhum dos dois.)

A página do console administrativo fica atrás do login administrativo e do segundo fator, e só para Administradores. A página pública só existe quando TestSignature:Enabled está ligada, o que coloca um formulário de assinatura na raiz do host; como as outras chaves que decidem o que fica exposto, ela é configuração da implantação, e nunca uma tela. Qualquer CPF pode ser testado ali, uma execução substitui uma sessão já ativa para aquele CPF e CNPJ, e um PIN errado conta para o bloqueio do titular, exatamente como contaria numa sessão criada com aquela chave a partir de qualquer cliente.

Deixe Diagnostics:ServerTiming desligada em produção. Com ela ligada, todo chamador que tenha uma chave de API fica sabendo quanto tempo o serviço de assinatura e os tokens da implantação levam, e quais sessões assinam numa estação de trabalho e não no cofre, o que o contrato, fora isso, esconde dele.

Contas administrativas e o segundo fator​

As Contas Administrativas são locais. Toda conta tem um Segundo Fator (TOTP de um aplicativo autenticador) nos dois perfis, cadastrado pelo próprio dono e conhecido por mais ninguém. Os Códigos de Recuperação são substitutos de uso único, emitidos em conjunto no cadastro e exibidos uma única vez. Um Administrador pode limpar o segundo fator de outra pessoa, o que invalida os Códigos de Recuperação dela e força um novo cadastro, mas nunca pode lê-lo nem defini-lo.

O que o banco de dados guarda. Senhas, chaves de API e Códigos de Recuperação são armazenados apenas como hash; um Código de Recuperação recebe hash da mesma forma que uma senha (PBKDF2 com salt), e os códigos gravados por um Servidor anterior à 1.10.0 recebem hash na primeira inicialização depois da atualização, sem desconectar ninguém. O segredo do autenticador é armazenado em texto claro, porque o Servidor precisa calcular códigos a partir dele a cada trinta segundos. Quem tiver uma cópia do banco de dados, como um backup roubado, consegue calcular os códigos do autenticador de qualquer administrador; a senha continua valendo, mas, para essa pessoa, a conta tem um fator, e não dois. Proteja os backups do banco de dados de acordo.

Admin:SecondFactor:Required (padrão true) é configuração da implantação e fica de fora, de propósito, da tela Configurações e usuários: um interruptor que desativa o segundo fator, acessível de dentro do próprio console que ele protege, é um interruptor que um invasor aciona no caminho. Uma linha salva no banco de dados com essa chave é ignorada. A mesma proteção vale para as chaves Admin:CertificateSignIn:* e para Vault:Enabled.

As senhas têm pelo menos doze caracteres. Não há e-mail de redefinição; um Administrador define uma senha nova na tela Configurações e usuários e a entrega pessoalmente, e as sessões existentes da conta terminam em até cinco minutos. Desativar uma conta a mantém, porque a Trilha de Auditoria atribui a ela as ações passadas.

Acesso com Certificado​

Onde a implantação ativa Admin:CertificateSignIn:Enabled, uma conta também pode ser aberta por um e-CPF ICP-Brasil lido pelo Lacuna Web PKI, sem senha e sem a etapa do Segundo Fator (Console administrativo). Isso se apoia em:

  • A posse é comprovada assinando um desafio gerado pelo Servidor: de uso único, de curta duração, vinculado ao nome de host e ao cookie de pré-autenticação do navegador, e assinado como bytes brutos, e não como um hash escolhido pelo Servidor. Isso impede a reutilização (replay), mas não o repasse em tempo real por uma página de outro domínio, que é o mesmo limite de um código de Segundo Fator repassado.
  • O certificado é validado como qualquer outro certificado da plataforma, contra as raízes da ICP-Brasil e as Autoridades Certificadoras Confiáveis do Servidor, com a revogação verificada a cada entrada. Só ACTIVE passa. Um e-CNPJ nunca abre a conta de ninguém.
  • O vínculo é um CPF, nunca um thumbprint ou um emissor. Qualquer certificado em que o Servidor confia e que traga o CPF vinculado de uma conta abre essa conta; assim, uma renovação continua funcionando, e também um certificado de qualquer autoridade em que o Servidor confia. Daí vêm duas consequências, ambas aceitas:
    • Um Administrador define todo CPF vinculado, e nunca o próprio. Ninguém comprova que um CPF é seu; ele é digitado na tela de contas, então um vínculo é exatamente tão confiável quanto o Administrador que o digitou. Um Administrador poderia digitar o próprio CPF na conta de um colega e entrar como ele; a linha admin.account-bound-cpf-set mostra quem fez isso, e a página da conta do colega mostra quem definiu o vínculo dele e quando.
    • Uma Autoridade Certificadora Confiável é uma emissora de credenciais para o console. Quem controla uma autoridade adicionada na tela Autoridades Certificadoras Confiáveis pode emitir um certificado com qualquer CPF vinculado e entrar como aquela conta. A linha admin.trusted-ca-added mostra quem a adicionou, e cada linha admin.certificate-sign-in registra o thumbprint e o emissor do certificado apresentado. Recuperar-se de uma sessão de Administrador comprometida inclui revisar as Autoridades Certificadoras Confiáveis que ela adicionou. Numa implantação com Certificates:Validation:UseLacunaTestPki ligada, uma conta vinculada ao CPF de um certificado de exemplo fica aberta a qualquer um que tenha baixado esse exemplo.
  • Há limite de requisições, e não bloqueio. O desafio é limitado a dez por minuto por endereço (um endereço IPv6 conta pelo /64), e no máximo oito verificações de certificado rodam ao mesmo tempo. Uma entrada por certificado que falha nunca afeta o bloqueio por senha, e uma conta bloqueada por senhas erradas ainda entra com o certificado. Atrás de um proxy reverso, o limite por endereço só conta navegadores onde o proxy está indicado em ForwardedHeaders:TrustedProxies (Postura de rede).
  • Substituir ou limpar um CPF vinculado encerra as sessões da pessoa em até cinco minutos, como definir uma senha. Para tomar de volta uma conta de alguém, limpe também o CPF vinculado dela, ou desative a conta.
  • A página de login lembra o caminho de entrada (Servidor 1.20.0). Uma senha ou um certificado aceito, mesmo que depois venha a etapa do Segundo Fator, grava um cookie, TrustBridge.SignInCredential, restrito a /admin/login e guardado por um ano, que diz qual dos dois foi usado, para que a página de login abra no mesmo da próxima vez. Ele não é uma credencial, não autoriza nada e sobrevive a uma saída. Ele só é gravado e lido enquanto o Acesso com Certificado está ligado, e a outra forma de entrar continua a um link de distância.

As senhas podem ser desligadas com Admin:CertificateSignIn:Required=true. Antes disso, confira que todas as pessoas que precisam do console têm um CPF vinculado, que existem pelo menos dois Administradores (um Administrador sozinho não tem quem defina o dele) e que o proxy reverso, se houver, está indicado. Ligar a opção não encerra as sessões já abertas com senha. A cada inicialização com ela ligada, o Servidor registra um aviso contando as contas ativas sem CPF vinculado, quantas delas são de Administradores e quantos Administradores ativos existem: quando o segundo número chega ao terceiro, ninguém consegue administrar a plataforma. O Servidor se recusa a iniciar com ela ligada enquanto Admin:CertificateSignIn:Enabled estiver desligada.

Acesso de emergência (break-glass): autenticador perdido​

Um Administrador que perdeu o dispositivo pode ficar sem acesso mesmo enquanto a plataforma acredita que outro Administrador consegue entrar. O caminho de volta é pela implantação, não pelas telas:

  1. Defina Admin:SecondFactor:Required=false e reinicie o Servidor.
  2. Deixe que ele entre com a senha e cadastre um autenticador novo.
  3. Volte a configuração para true e reinicie.

O Servidor anuncia a postura enfraquecida em toda inicialização enquanto ela estiver desligada, não só na primeira, porque um acesso de emergência que ninguém fechou de novo é justamente a falha sobre a qual vale avisar.

Acesso de emergência (break-glass): nenhum certificado consegue entrar​

Com as senhas desligadas, várias coisas encerram todo Acesso com Certificado de uma vez: remover a Autoridade Certificadora Confiável pela qual os certificados dos administradores encadeiam, uma licença da PKI vencida, uma licença do Web PKI que não cobre mais o nome de host que as pessoas digitam, uma atualização do navegador que quebre a extensão, ou o CPF vinculado do último Administrador limpo. O Servidor nunca se recusa a iniciar por causa disso, então:

  1. Defina Admin:CertificateSignIn:Required=false e reinicie. A entrada por senha volta, com a senha e o Segundo Fator de cada conta onde estavam.
  2. Entre com uma senha e corrija o que impediu os certificados.
  3. Volte a configuração para true e reinicie. Nada vai lembrar você de fazer isso.

Admissão de estações de trabalho​

Uma máquina não tem segredo compartilhado com que entrar na plataforma, e procurar um é procurar algo que o produto deliberadamente não tem. Ela gera uma Chave da Estação de Trabalho no TPM, quando há um utilizável (senão, em software), se anuncia e aguarda que um Administrador a admita. Depois de admitida, ela se prova a cada conexão com uma Asserção da Estação de Trabalho assinada e de curta duração, em vez de uma credencial: nada é emitido, nada é armazenado, e uma asserção capturada já foi consumida.

A Installer Key, que também assina a requisição de admissão, serve contra abusos, não para autenticação: toda cópia do TrustBridge tem a metade privada do produto. Uma implantação que queira uma chave que ninguém mais tenha gera uma, informa a metade pública dela em Admission:InstallerKeys (o que substitui a chave do produto) e entrega a metade privada pelo próprio instalador.

O valor da admissão é limitado, e a tela diz isso: sem um canal externo (out-of-band) com que conferir uma impressão digital, uma máquina é notada, e não verificada. Os controles em volta dela: Admission:MaxPending limita a fila, Admission:RequestsPerAddress limita um endereço de origem (um endereço IPv6 conta pelo /64), Admission:PendingExpiry faz expirar requisições abandonadas e Admission:RequireHardwareBackedKeys recusa máquinas com chave em software. A postura da chave é declarada pela própria máquina; atestação de TPM está fora do escopo.

Uma máquina admitida também escolhe quais linhas de certificado anuncia, e é por isso que ela nunca recebe um PIN: um anúncio pode trazer o certificado verdadeiro e público de um titular, então o Servidor só pede a uma máquina que prove que tem o PIN, e limita as provas que falham (Tratamento do PIN).

A revogação na tela Estações de Trabalho recusa uma máquina enquanto a linha dela existir e não depende da cooperação dela. Uma máquina cujo disco foi clonado com uma chave em software é uma identidade clonada, e é isso que a postura de exigir hardware existe para recusar.

Remover (Servidor 1.21.0) é uma tarefa de organização ao lado de Revogar, e não um controle de segurança. Remover esquece uma máquina que já foi admitida alguma vez: a linha dela, as entradas dela no Registro de Certificados, o Relatório da Estação de Trabalho dela, as Provas de PIN com falha dela e, junto com a linha, o bloqueio sobre a chave dela, de modo que a mesma chave, ao pedir de novo, chega como uma máquina Pendente nova, que um Administrador precisa admitir. Remover uma máquina Revogada, portanto, levanta a recusa dela, e a confirmação avisa isso. Uma máquina perdida, roubada ou comprometida é revogada; uma implantação que queira um bloqueio permanente não a remove depois. Uma máquina conectada é desconectada ao ser removida, e uma sessão ainda vinculada a ela não assina mais nada. A Trilha de Auditoria mantém todas as linhas sobre a máquina e ganha uma linha admin.workstation-removed que a identifica por completo, e as Sessões de Assinatura e Operações de Assinatura feitas por meio dela continuam existindo.

Âncoras de confiança​

A plataforma confia nas raízes da ICP-Brasil que o PKI SDK traz por padrão. Uma autoridade certificadora privada é adicionada como Autoridade Certificadora Confiável (Trusted CA) no console administrativo, passa a valer no Servidor em execução e é enviada a todas as máquinas admitidas. Quem pode adicionar uma Autoridade Certificadora Confiável pode fazer certificados próprios serem validados como ACTIVE e, onde o Acesso com Certificado está ativado, entrar no console como qualquer conta cujo CPF vinculado coloque num deles. Por isso a ação é de um Administrador e é auditada, e por isso uma autoridade descoberta pela web, a partir de uma URL indicada pelo próprio certificado não confiável, é sinalizada para conferência da impressão digital antes de ser confirmada.

Em uma estação de trabalho, os arquivos de âncora em C:\ProgramData\TrustBridge\anchors\ são o equivalente, protegidos por uma ACL que pertence ao instalador, e são desconsiderados enquanto a máquina tiver um conjunto não vazio recebido do Servidor.

Dois interruptores ampliam a confiança e merecem atenção: UseMachineRootStore (todas as ACs públicas do programa de raízes do Windows, em uma estação de trabalho) e UseLacunaTestPki (somente para desenvolvimento: a Lacuna publica as chaves privadas desses certificados de exemplo, e um Servidor com ele ligado exibe um banner de aviso em todas as páginas administrativas).

Certificates:Validation:RevocationGraceWindow (24 h) é a outra decisão de confiança: exatamente por quanto tempo um certificado continua assinando depois que a AC dele parou de responder, revogado ou não. Zero é a postura mais rígida.

Documentos assinados com o REST PKI Core​

Desde o Servidor 1.18.0, um Administrador pode configurar uma Aplicação Cliente para que os documentos dela sejam assinados com o REST PKI Core em vez do Lacuna Signer. O REST PKI Core monta o PDF assinado em torno da única assinatura que a chave do titular faz; ele nunca tem a chave, e a custódia, o PIN, o Cache de PIN e as Autorizações de assinatura funcionam exatamente como antes. O que muda:

  • O REST PKI Core guarda os documentos assinados. O TrustBridge continua sem guardar nenhum. Por quanto tempo o REST PKI Core guarda um documento é configuração dele, e o TrustBridge não tem uma chamada que o exclua lá. Conforme as configurações do plano contratado, o REST PKI Core também pode marcar as páginas. A opção na tela Aplicações Cliente diz as duas coisas.
  • A confiança dele é a do contexto de segurança, e não a das Autoridades Certificadoras Confiáveis. O REST PKI Core valida o certificado do titular com o contexto de segurança que a implantação configurou (RestPkiCore:SecurityContextId), e as Autoridades Certificadoras Confiáveis do console administrativo não são aplicadas a ele. Uma implantação cujos titulares vêm de autoridades certificadoras de fora da ICP-Brasil precisa de um contexto de segurança personalizado, mantido em sincronia com as Autoridades Certificadoras Confiáveis dela à mão. O veredito da própria plataforma continua decidindo toda assinatura; o do REST PKI Core é uma segunda verificação, e os dois podem discordar, caso em que o cliente recebe CERT_NOT_ACTIVE. O REST PKI Core verifica a revogação na hora, então a RevocationGraceWindow da plataforma não vale para ele, a menos que o contexto de segurança esteja configurado para ignorar uma situação de revogação desconhecida.
  • RestPkiCore:ApiKey é um segredo, de uma aplicação do REST PKI Core com o papel Worker, e vai em toda requisição, e é por isso que o Servidor se recusa a iniciar com um RestPkiCore:Endpoint que não seja https.
  • O Servidor acessa dois endereços do REST PKI Core: o endpoint e o endereço do site, de onde um documento assinado é baixado por uma URL que traz o próprio tíquete de acesso, expira em cerca de uma hora e nunca é guardada.
  • Uma recusa depois de a chave do titular ter assinado não garante nada, num sentido ou noutro: o REST PKI Core pode ter um documento assinado que nenhuma Operação de Assinatura identifica. Quando uma conclusão fica sem resposta, o log do Servidor diz isso numa linha Error.

A licença da PKI​

Certificates:Validation:License é obrigatória em todo Servidor, com ou sem cofre: um Servidor sem ela se recusa a iniciar. Ela também é a licença com que a frota inteira funciona. O Servidor a entrega a cada máquina admitida no handshake, e só ali; uma máquina pendente nunca a recebe. A máquina a guarda somente em memória e a recebe de novo a cada conexão; por isso, renová-la significa trocar o valor no Servidor e reiniciá-lo, e a frota a recebe à medida que se reconecta. Nada sobre a licença é gravado na configuração ou no registro de uma estação de trabalho: uma licença XML é gravada num arquivo temporário pelo tempo de um carregamento e apagada em seguida, porque o SDK só lê XML de um arquivo. O valor é mascarado onde quer que o handshake apareça no log.

Uma licença que o SDK recusa deixa todo certificado UNTRUSTED, no Servidor e em cada máquina a que é entregue, então nada consegue assinar e nenhum Acesso com Certificado funciona. Uma licença recusada na inicialização coloca um banner em todas as páginas administrativas.

Atualizações entregues pelo Servidor​

Um Administrador pode enviar uma versão do Workstation na tela Versões da Estação de Trabalho e oferecê-la às máquinas, que a instalam sem ninguém presente. O canal foi feito para que o Servidor não consiga fazer uma máquina executar nada além de um pacote genuíno e mais novo do TrustBridge Workstation:

  • O Servidor recusa um upload sem assinatura, assinado por um certificado fora do Publisher Pin compilado no Servidor, ou que fale um protocolo fora da janela do Servidor. Toda versão do Workstation a partir da 1.2.2 é assinada com Authenticode pela Lacuna Software, com carimbo de tempo RFC 3161.

  • A máquina confere o pacote ela mesma, nesta ordem, e o recusa na primeira falha, o que quer que o Servidor tenha dito sobre ele:

    1. o SHA-256 e o tamanho que o Servidor anunciou;
    2. a assinatura Authenticode;
    3. um carimbo de tempo RFC 3161;
    4. um assinante que esteja no Publisher Pin compilado no Service já instalado, e não no que está chegando;
    5. a revogação, em que só passa uma verificação bem-sucedida ou uma consulta que não pôde ser respondida;
    6. o UpgradeCode do próprio TrustBridge Workstation;
    7. uma ProductVersion igual à oferecida e acima da instalada.

    Assim, o pior que um Servidor comprometido consegue fazer por esse canal é instalar antes da hora uma versão genuína e mais nova: nunca outro arquivo, outro produto ou uma versão mais antiga.

  • O download é autenticado pela chave da máquina. Cada requisição a GET /workstations/releases/{version} traz uma Asserção da Estação de Trabalho nova, e uma máquina só recebe a versão oferecida a ela. O pacote vai para C:\ProgramData\TrustBridge\updates\, em que só SYSTEM e os Administradores podem gravar.

  • O operador pode desligá-las por máquina com a Política de Grupo Receber atualizações do Servidor TrustBridge; a tela Estações de Trabalho passa a mostrar Atualizações desativadas por política.

O Relatório da Estação de Trabalho​

A partir do Workstation 1.8.0, uma máquina informa ao Servidor a própria situação, sem que ninguém peça, depois de cada handshake e sempre que essa situação muda, para que o suporte veja o problema de uma máquina sem estar diante dela. O Relatório da Estação de Trabalho traz:

  • a licença da PKI como a máquina a tem, a versão do runtime do .NET dela e as opções com que ela roda;
  • o middleware que ela consulta, com o caminho de cada módulo, a versão do arquivo dele e se ele foi carregado;
  • cada token que ela enxerga, por fabricante, modelo e número de série, com os CPFs dos certificados dele e quão perto o PIN dele está de bloquear;
  • as leitoras de cartão que o Windows deixou com falha, com os ids de instância de dispositivo delas;
  • os erros que o Workstation Service e o Tray App registraram em Error ou Critical, agrupados por modelo de mensagem, com os valores do modelo, a categoria do logger e o tipo e a mensagem da exceção;
  • a partir do Workstation 1.10.0, o console dela: a Conta no console conectada ali, pelo SID do Windows e pelo nome DOMÍNIO\usuário quando ele pode ser resolvido, se essa sessão está bloqueada, se um Tray App roda nela e em qual versão, e quantas outras sessões têm um, sem as contas delas. O próprio serviço lê a conta, então ela é informada mesmo sem nenhum Tray App rodando, e o relatório é enviado de novo quando alguém entra ou sai da sessão, bloqueia ou desbloqueia a máquina, troca de usuário, ou quando um Tray App se conecta ou se desconecta.

PINs em qualquer forma, bytes de documentos e bytes de assinaturas nunca são enviados. CPFs, números de série de tokens, a Conta no console e os valores de uma linha de log podem ser. O Servidor guarda o último relatório de cada máquina, o mostra a quem pode ler a tela Estações de Trabalho e exclui um grupo de erros ao qual nenhum relatório acrescentou nada durante WorkstationReports:ErrorRetentionDays (30 dias por padrão); nada num relatório grava uma linha na Trilha de Auditoria. Uma máquina pode ser configurada para não informar, com WorkstationReport:Enabled, a propriedade WORKSTATION_REPORT do MSI ou a Política de Grupo Informar a situação desta máquina ao TrustBridge Server: ela então diz só que não informa, e o Servidor esquece o que tinha sobre ela. A mesma opção mantém o console na máquina: com ela desligada, nenhuma conta nem outra parte do console sai dela. Remover uma máquina exclui o relatório dela.

Segredos e os logs​

O Servidor e o Workstation Service mantêm segredos fora do que imprimem. No Servidor, senhas, códigos do Segundo Fator, o segredo do autenticador, o valor e o hash de uma chave de API nova e a licença da PKI entregue a uma máquina são mascarados onde quer que um comando ou um resultado fosse para o log. Numa estação de trabalho, o PIN e qualquer Prova de PIN nunca são impressos. O Tray App não grava arquivo de log nenhum, porque a linha de um pedido de PIN cita um CPF. Um CPF aparece, sim, em linhas do log do Servidor e da Trilha de Auditoria sobre uma sessão ou um limite, como sempre apareceu. A partir do Workstation 1.8.0, as linhas Error e Critical do Workstation Service e do Tray App, com os valores delas, também chegam ao Servidor no Relatório da Estação de Trabalho, a menos que a máquina seja configurada para não informar.

Postura de rede​

  • As estações de trabalho só fazem conexões de saída, por HTTPS até o Servidor. Nenhuma porta de entrada é aberta na máquina, e o canal entre o Service e o Tray é um named pipe local cuja ACL é todo o controle de acesso dele.
  • O Servidor termina o próprio TLS no Docker e precisa apresentar uma cadeia em que todas as estações de trabalho confiem; um proxy reverso pode terminá-lo no lugar dele. No App Service, a plataforma o termina.
  • O endereço de quem chama só vem de proxies que você indica. No Docker, atrás do seu próprio proxy, liste-o em ForwardedHeaders:TrustedProxies (endereços ou CIDRs; no ambiente, ForwardedHeaders__TrustedProxies__0, …__1). X-Forwarded-For e X-Forwarded-Proto só são aceitos de um par listado; o Host e o caminho nunca são reescritos. No App Service, ASPNETCORE_FORWARDEDHEADERS_ENABLED=true faz o mesmo papel; fora do App Service, essa variável confia em quem quer que se conecte e o Servidor avisa na inicialização, e um Servidor com as duas definidas se recusa a iniciar. O custo de deixar um proxy sem indicação: o ClientIp da Trilha de Auditoria, o limite por endereço da admissão e o limite do Acesso com Certificado enxergam todos o único endereço do proxy, então qualquer pessoa que consiga acessar a página de login consegue gastar as tentativas de entrada de todo mundo.
  • Oito áreas compartilham uma porta, distinguidas pelo caminho: o contrato em /v1, o canal das estações de trabalho, a admissão de estações de trabalho, o download de Versões da Estação de Trabalho, a documentação publicada, a Landing Page, o health probe e as páginas administrativas. Um caminho fora de todas elas recebe um 401 de chave de API antes que um navegador o veja. /healthz, / e a documentação respondem sem credencial e, de propósito, não revelam nada sobre o estado da plataforma. O cookie administrativo só é aceito nos caminhos administrativos.
  • O throttle global (Throttle:ConcurrencyLimit, 200) é um disjuntor (circuit breaker) sobre a superfície do contrato contra um cliente descontrolado e não pode ser desligado.
  • Nunca execute uma implantação com ASPNETCORE_ENVIRONMENT=Development: a imagem traz um arquivo de configuração de desenvolvimento com uma licença de exemplo e as credenciais de um Signer de testes compartilhado, inofensivos apenas porque uma implantação é Production.

O que é gravado onde​

RegistroContémNunca contém
Trilha de Auditoria (banco de dados)Autor, ids dos objetos, resultado e timestamps de cada chamada à API, evento de sessão e de assinatura (inclusive cada hash da Assinatura de hash e cada Autorização de assinatura), evento de estação de trabalho, de PIN e de atualização, Assinatura de teste, ação administrativa e entrada no console; a partir do Servidor 1.24.0, o código de erro com que uma chamada à API foi respondidaPINs, Provas de PIN, chaves de API, conteúdo de documentos, bytes de assinatura, a mensagem e os detalhes de um erro
Log do Servidor (console, arquivo rotativo, Application Insights)O que o Servidor estava fazendo, com um id de correlação; linhas de auditoria que o banco de dados recusou, em CriticalPINs, Provas de PIN, senhas, códigos, material de chave, a licença da PKI
Log do Workstation Service (log de eventos Aplicativo, painel de diagnóstico do Tray)De onde veio cada valor definido na instalação, estado da conexão, recusas, vereditos, resultados de atualizaçãoPINs, Provas de PIN
Banco de dados (SQL Server, ou PostgreSQL no Docker)Sessões, operações, Registro de Certificados, texto cifrado do cofre, os dois chaveiros, contas administrativas (hashes de senhas e de Códigos de Recuperação, segredos do autenticador em texto claro, CPFs vinculados), Provas de PIN com falha, valores alterados nas configurações, Versões da Estação de Trabalho (os pacotes inteiros) e as ofertas delas, o último Relatório da Estação de Trabalho de cada máquina (números de série e CPFs dos tokens, middleware, leitoras com falha, grupos de erros, a Conta no console), as contagens da Atividade de assinatura (que não identificam nenhum titular)O Protetor do Chaveiro, qualquer documento assinado (do Signer ou do REST PKI Core), qualquer PIN
/tmp/trustbridge-releases (Servidor)Uma cópia de cada Versão da Estação de Trabalho armazenada, de onde os downloads são servidos, e um upload enquanto é lidoNada que já não esteja no banco de dados
C:\ProgramData\TrustBridge\ (estação de trabalho; só Administradores e SYSTEM)O arquivo do Cache de PIN quando PinCache:SurviveRestart está ligada, o conjunto de Autoridades Certificadoras Confiáveis em cache, os verificadores dos PINs do Certificado A1, os arquivos de âncora; em updates\, uma versão sendo instalada e os cinco logs de instalação mais recentesA licença da PKI, qualquer PIN do Certificado A1 em si

Nada em nenhum dos componentes grava documentos em disco. Os documentos ficam só em trânsito, em memória, limitados a Signing:MaxDocumentBytes vezes Signing:MaxBatchItems. Um documento assinado fica guardado no serviço de assinatura que o montou: o Lacuna Signer, ou o REST PKI Core para uma Aplicação Cliente configurada para usá-lo.

Ver em Markdown