---
title: "Autenticação com certificado - Rest PKI Core"
description: "Login com certificado digital: o Rest PKI Core prepara um nonce, o Web PKI o assina no navegador e o CompleteAuthenticationAsync valida o certificado."
canonical: "https://docs.lacunasoftware.com/articles/rest-pki/core/integration/cert-auth"
locale: "pt-BR"
product: "Rest PKI Core"
last_updated: "2026-10-12"
---

# Autenticação com certificado - Rest PKI Core

Os usuários podem entrar na sua aplicação com o certificado digital deles. O [Rest PKI Core](https://docs.lacunasoftware.com/articles/rest-pki/core) faz a parte do backend do processo de
[login com certificado](https://docs.lacunasoftware.com/articles/pki-guide/cert-auth), e o [Web PKI](https://docs.lacunasoftware.com/articles/web-pki), a parte que roda no navegador:

1. O seu servidor pede ao Rest PKI Core que **prepare** uma autenticação. O Rest PKI Core gera um *nonce* aleatório e retorna o hash a ser assinado e o
   estado da autenticação (*state*).
1. Na sua página, o usuário escolhe um certificado, e o Web PKI assina o hash com ele. A página envia a codificação do certificado, a assinatura e o
   estado ao seu servidor.
1. O seu servidor os envia ao Rest PKI Core, que **conclui** a autenticação: verifica a assinatura, valida o certificado e confere se o *nonce* já não
   foi usado.
1. Se a autenticação for bem-sucedida, a sua aplicação localiza o usuário por um campo do certificado, como o CPF ou o e-mail, e conclui o login.

> **Dica**
>
> Desse ponto em diante estaremos descrevendo chamadas ao Rest PKI Core. Para conseguir acompanhar, certifique-se de que já fez os
> [Primeiros passos](https://docs.lacunasoftware.com/articles/rest-pki/core/integration/get-started). A chave de API da aplicação precisa de um papel que permita autenticar usuários com certificados, como o **Operador**
> (veja [Escolhendo os papéis](https://docs.lacunasoftware.com/articles/rest-pki/core/integration/get-started#roles)). Fora do *localhost*, o Web PKI precisa de uma [licença](https://docs.lacunasoftware.com/articles/web-pki/licensing).

## Preparando a autenticação

Em .NET, chame `IRestPkiService.PrepareAuthenticationAsync()`:

```cs
var prepareAuthResult = await restPkiService.PrepareAuthenticationAsync(securityContextId: securityContextId);

// Repasse estes valores à página
var state = prepareAuthResult.State;
var toSignHash = Convert.ToBase64String(prepareAuthResult.ToSign.Hash);
var digestAlgorithm = prepareAuthResult.ToSign.SignatureAlgorithm.DigestAlgorithm.Oid;
```

* O `securityContextId` decide em quais certificados confiar. Se omitido, o Rest PKI Core usa o contexto de segurança padrão da organização ou, na falta
  dele, o da instância.
* O `ignoreRevocationStatusUnknown` aceita certificados cujo status de revogação não pode ser determinado. Se omitido, vale a configuração da organização
  ou, na falta dela, a da instância.

O resultado traz o hash a assinar em `ToSign.Hash`, o algoritmo de hash em `ToSign.SignatureAlgorithm.DigestAlgorithm` e o estado em `State`, uma string
opaca de que o Rest PKI Core precisa para concluir a autenticação. Preparar uma autenticação não grava nada no Rest PKI Core; por isso, você pode
prepará-la toda vez que a sua página de login for exibida.

Em Java, chame `RestPkiService.prepareAuthentication()`:

```java
PrepareAuthenticationOptions options = new PrepareAuthenticationOptions();
options.setSecurityContext(SecurityContext.pkiBrazil);
PrepareAuthenticationResult prepareAuthResult = restPkiService.prepareAuthentication(options);

// Repasse estes valores à página
String state = prepareAuthResult.getState();
String toSignHash = prepareAuthResult.getToSignHash().getValueAsBase64();
String digestAlgorithm = prepareAuthResult.getToSignHash().getAlgorithm().getName();
```

Caso esteja chamando a API diretamente:

```text
POST {endpoint}/api/v2/authentication
{
	"securityContextId": "...",
	"ignoreRevocationStatusUnknown": false
}
```

A resposta traz o hash a assinar em `toSign.hash` (em Base64), o algoritmo de hash em `toSign.signatureAlgorithm.digestAlgorithmOid` e o estado em
`state`. Ela também repete o hash em `toSignHash`, para clientes mais antigos.

## Assinando o hash na sua página

O certificado do usuário nunca sai do computador dele; por isso, o Web PKI assina o hash no navegador:

1. Liste os certificados do usuário com o `listCertificates()` do Web PKI.
1. Quando o usuário escolher um, leia a codificação dele com o `readCertificate()` e assine o hash com o `signHash()`.
1. Envie a codificação do certificado e a assinatura, ambas em Base64, e o estado ao seu servidor, que
   [conclui a autenticação](https://docs.lacunasoftware.com/articles/rest-pki/core/integration/cert-auth#concluindo-a-autenticação).

```javascript
pki.readCertificate({ thumbprint: thumbprint }).success(function (certificate) {
	pki.signHash({
		thumbprint: thumbprint,          // o certificado escolhido pelo usuário
		hash: toSignHash,                // o hash a assinar, em Base64
		digestAlgorithm: digestAlgorithm // o algoritmo de hash, como recebido do seu servidor
	}).success(function (signature) {
		// Envie o certificado, a assinatura (ambos em Base64) e o estado ao seu servidor
	});
});
```

O estado é protegido pelo Rest PKI Core; por isso, você pode guardá-lo num campo oculto da página. Para o `listCertificates()`, o `readCertificate()` e o
`signHash()`, veja os [Primeiros passos](https://docs.lacunasoftware.com/articles/web-pki/get-started) do Web PKI.

## Concluindo a autenticação

Em .NET, chame `IRestPkiService.CompleteAuthenticationAsync()` com o estado, o certificado e a assinatura:

```cs
var authResult = await restPkiService.CompleteAuthenticationAsync(
	state,
	Convert.FromBase64String(certificate),
	Convert.FromBase64String(signature)
);
if (authResult.Success) {
	var userCert = authResult.Certificate;
	// Localize o usuário por um campo do certificado, como userCert.PkiBrazil.Cpf ou userCert.EmailAddress, e conclua o login
} else {
	// authResult.Failure diz o motivo
}
```

Quando `Success` é `false`, `Failure` diz o motivo:

| `Failure` | O que aconteceu | O que fazer |
| --- | --- | --- |
| `CertificateFailedValidation` | O certificado não é válido no contexto de segurança, por exemplo por estar revogado ou não ser confiável | Mostre os motivos, em `ValidationResults` |
| `StaleSession` | A autenticação expirou antes de ser concluída: por padrão, uma autenticação dura 60 minutos | Prepare uma nova autenticação |
| `NonceReused` | O estado já foi usado para concluir uma autenticação, o que pode indicar um ataque de replay | Prepare uma nova autenticação |

Se a assinatura não corresponder ao hash, o que costuma indicar um erro na sua página, o Rest PKI Core responde com HTTP 422 e o código de erro
`BadSignature` (veja [Erros](https://docs.lacunasoftware.com/articles/rest-pki/core/integration/get-started#dotnet-errors)).

Em Java, chame `RestPkiService.completeAuthentication()`:

```java
CompleteAuthenticationOptions request = new CompleteAuthenticationOptions();
request.setCertificateFromBase64(certificate);
request.setSignatureFromBase64(signature);
request.setState(state);

AuthenticationResult authResult = restPkiService.completeAuthentication(request);
if (authResult.isSuccess()) {
	// authResult.getCertificate() é o certificado do usuário
} else if (authResult.getFailure().equals(AuthenticationFailures.CERTIFICATEFAILEDVALIDATION)) {
	// authResult.getValidationResults() diz por que o certificado foi recusado
} else {
	// Prepare uma nova autenticação
}
```

Caso esteja chamando a API diretamente:

```text
POST {endpoint}/api/v2/authentication/completion
{
	"state": "...",
	"certificate": "Base64EncodedCertificate==",
	"signature": "Base64EncodedSignature=="
}
```

A resposta traz `success`, `failure`, o certificado do usuário em `certificate` e, quando o certificado foi validado, os resultados em
`validationResults`.

> **Observação**
>
> O Rest PKI Core também atende à API de autenticação do [Rest PKI](https://docs.lacunasoftware.com/articles/rest-pki/certificate-authentication) clássico (`Api/Authentications`), o que
> facilita levar ao Rest PKI Core uma aplicação que autentica com o Rest PKI. Veja
> [Migração do Rest PKI para o Rest PKI Core](https://docs.lacunasoftware.com/articles/rest-pki/core/integration/migrating-from-rest-pki).

## Exemplos

* Java: [AuthenticationRestPkiCoreController.java](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/java/springmvc/src/main/java/com/lacunasoftware/pkisuite/controller/AuthenticationRestPkiCoreController.java)

**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 Rest PKI Core: [Java](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/java/springmvc/src/main/java/com/lacunasoftware/pkisuite/controller/AuthenticationRestPkiCoreController.java)
