---
title: "Autenticação com certificado - PKI Express"
description: "Autenticação com certificado digital com o PKI Express e o Web PKI: o PKI Express emite um nonce, o Web PKI o assina com o certificado do usuário e o PKI Express valida a assinatura e o certificado."
canonical: "https://docs.lacunasoftware.com/articles/pki-express/authentication"
locale: "pt-BR"
product: "PKI Express"
last_updated: "2026-10-12"
---

# Autenticação com certificado - PKI Express

Os usuários entram na sua aplicação com o certificado digital: o [PKI Express](https://docs.lacunasoftware.com/articles/pki-express) emite um nonce (um valor aleatório), o
[Web PKI](https://docs.lacunasoftware.com/articles/web-pki) o assina com o certificado do usuário no navegador, e o PKI Express valida a assinatura e o certificado. 
O PKI Express acrescentou isso na 1.4.0, com os comandos `start-auth` e `complete-auth`. 

O código é Java, dos [samples do PKI Suite](https://github.com/LacunaSoftware/PkiSuiteSamples), com o `com.lacunasoftware.pkiexpress:pki-express`
(1.20.0); o script do navegador é o mesmo no sample em Node.js. 
Para o método em si, veja [Login com certificado digital](https://docs.lacunasoftware.com/articles/pki-guide/cert-auth) no guia de soluções para certificação digital.

## Fluxo

1. **Servidor**: `start()` devolve o nonce e o algoritmo de hash; a página recebe os dois em campos ocultos.
1. **Navegador**: o Web PKI lista os certificados do usuário, lê o que ele escolher e assina o nonce com `signData()`; o script preenche o
   certificado e a assinatura e envia o formulário.
1. **Servidor**: `complete()` com o nonce, o certificado e a assinatura devolve os resultados da validação e o certificado.
1. **Servidor**: se os resultados forem válidos, encontre o seu usuário por um campo do certificado e faça o login dele.

## 1. Iniciar a autenticação

```java
Authentication auth = new Authentication();
Util.setPkiDefaults(auth);
AuthStartResult result = auth.start();
Util.setNoCacheHeaders(response);
model.addAttribute("nonce", result.getNonce());
model.addAttribute("digestAlgorithm", result.getDigestAlgorithm());
```

* O nonce vale para uma única tentativa de autenticação. O sample envia headers que impedem o navegador de guardar a página em cache
  (`Cache-Control: no-cache, no-store, must-revalidate`, `Pragma: no-cache`, `Expires: -1`), para que o botão voltar não mostre um nonce
  antigo. 
* `Util.setPkiDefaults()` aplica as raízes confiáveis, que decidem quais certificados são aceitos (veja
  [Quais certificados são confiáveis](https://docs.lacunasoftware.com/articles/pki-express/validate-signatures#quais-certificados-são-confiáveis)). 
* O PKI Express guarda os nonces que emitiu em um repositório de nonces, a `transferDataFolder` (por padrão, a pasta temporária), para
  verificá-los no `complete()`. Para guardar os nonces no seu próprio repositório e verificá-los você mesmo, ative o armazenamento externo. 
  A biblioteca Python (1.10.4) inverte essa opção: ela só passa o repositório de nonces quando o armazenamento externo está ativo. 
  TODO(docs): se o PKI Express verifica a reutilização do nonce quando nenhum repositório de nonces é informado.

## 2. Assinar o nonce no navegador

A página coloca `nonce` e `digestAlgorithm` em campos ocultos, com campos para o certificado (`certContent`) e para a assinatura
(`signature`). 
Quando o usuário entra, o script lê o certificado escolhido, assina o nonce com `signData()` e envia o formulário: 

```js
var selectedCertThumbprint = formElements.certificateSelect.val();
pki.readCertificate(selectedCertThumbprint).success(function (certEncoded) {
	pki.signData({
		thumbprint: formElements.certificateSelect.val(),
		data: formElements.nonceField.val(),
		digestAlgorithm: formElements.digestAlgorithmField.val()
	}).success(function (signature) {
		formElements.signatureField.val(signature);
		formElements.certContentField.val(certEncoded);
		formElements.form.submit();
	});
});
```

* O nonce é o dado a assinar, não um hash, por isso o script usa `signData`, e não `signHash`. Veja
  [Qual é a diferença entre as funções signData e signHash?](https://docs.lacunasoftware.com/articles/web-pki/faq/sign-data-vs-hash). 
* Antes disso, o script inicializa o Web PKI com `pki.init()` e lista os certificados com `listCertificates()`, marcando os vencidos. 

## 3. Concluir a autenticação

```java
Authentication auth = new Authentication();
Util.setPkiDefaults(auth);
auth.setNonce(nonce);
auth.setCertificateBase64(certContent);
auth.setSignature(signature);
AuthCompleteResult result = auth.complete();

ValidationResults vr = result.getValidationResults();
if (!vr.isValid()) {
	String vrHtml = vr.toString()
		.replaceAll("\n", "<br>")
		.replaceAll("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
	model.addAttribute("vrHtml", vrHtml);
	return "authentication-express/failed";
}

model.addAttribute("userCert", result.getCertificate());
```

* Aplique as mesmas configurações de confiança do início: o sample chama `Util.setPkiDefaults()` nas duas etapas. 
* As outras bibliotecas dão outros nomes às entradas: Node.js `setNonce`, `setCertificateFromBase64` (devolve uma Promise) e `setSignature`;
  PHP `setNonce`, `setCertificateBase64` e `setSignature`; Python as propriedades `nonce_base64`, `certificate_base64` e
  `signature_base64`. 
* Um nonce desconhecido falha com o código de retorno 28 (`NonceNotFound`), e uma assinatura inválida com o 08 (`BadSignature`). Veja os
  [códigos de retorno](https://docs.lacunasoftware.com/articles/pki-express/return-codes). 

## 4. Fazer o login do usuário

Quando os resultados são válidos, procure o seu usuário por um dos campos do certificado, como `getEmailAddress()` ou, em certificados
ICP-Brasil, `getPkiBrazil().getCpf()`; qual campo usar depende da sua aplicação. 
A página de sucesso do sample mostra o nome comum do titular, o e-mail, o tipo de certificado ICP-Brasil, CPF, responsável, empresa, CNPJ,
RG e OAB. 

## Veja também

* [Validar assinaturas](https://docs.lacunasoftware.com/articles/pki-express/validate-signatures)
* [Login com certificado digital](https://docs.lacunasoftware.com/articles/pki-guide/cert-auth) no guia de soluções para certificação digital
* [Referência rápida do PKI Express](https://docs.lacunasoftware.com/articles/pki-express/quick-reference)

**Demonstrações e exemplos**

- Demonstração: [Your certificates in the browser](https://try.lacunasoftware.com/pt/web-pki/certificates-in-the-browser)
- Authenticate with a digital certificate using PKI Express: [Java](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/java/springmvc/src/main/java/com/lacunasoftware/pkisuite/controller/AuthenticationExpressController.java) · [Node.js](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/nodejs/expressmvc/routes/authentication-express.js) · [PHP](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/php/plain/public/authentication-express/index.php) · [Python](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/python/flask/sample/views/authentication_express.py)
