Pular para o conteúdo principal

Rest PKI quick reference (legacy)

The essentials of Rest PKI on one page, with links to the full articles.

Legacy product

Rest PKI, the cloud service at pki.rest, is a legacy product: it still receives bug and security fixes, but for a new cloud integration, use Rest PKI Core. Rest PKI Core also serves most of the APIs of the classic Rest PKI (PAdES, CAdES and XML signatures, certificate authentication and PDF marks), which eases moving an application to it.

TODO(docs): there is no guide to moving an application from Rest PKI to Rest PKI Core. Rest PKI still gets releases (1.33.9 on 2026-09-08).

What it is for​

Rest PKI is a cloud service for PKI operations such as digital signatures and certificate authentication, used from virtually any programming language through client libraries; you can also host your own instance on Windows Server or Azure App Service. In a web application it works with Web PKI: your backend starts the operation and gets a single-use token, Web PKI's signWithRestPki() signs in the browser, and your backend finishes the operation with that token.

Choose insteadWhen it fits better
Rest PKI CoreYou start a new cloud integration: signatures, validation, timestamps and biometric checks through a REST API, at core.pki.rest or on your own instance, with signing pages it hosts for you.
PKI ExpressYou sign on your own Windows or Linux servers from virtually any language. For Linux, the Rest PKI on-premises article recommends PKI Express instead.
PKI SDKYour backend is .NET: the PKI guide recommends PKI SDK for server signatures in .NET, and it can do the server side of web signatures with Web PKI.
Web PKIYou need only the browser side: list the user's certificates, read them and sign with them in JavaScript. Rest PKI uses it for that step.

Install​

LanguagePackageCurrent majorRegistry
.NET (C#, VB.NET, C++.NET)Lacuna.RestPki.Client5 (latest 5.0.0); 1.24.1 for .NET Framework 3.5 to 4.6NuGet
Java 7+com.lacunasoftware.restpki:restpki-client1 (latest 1.15.11, for Java 8+; on Java 7, 1.15.7)Maven Central
Java 6com.lacunasoftware.restpki:restpki-client-java61 (latest 1.9.0)Maven Central
PHP 5.5+lacuna/restpki-client2 (latest 2.9.10)Packagist
PHP 5.3 and 5.4lacuna/restpki-client-legacy1 (latest 1.1.0)Packagist
Node.jsrestpki-client2 (latest 2.3.8)npm
Pythonrestpki-client1 (latest 1.3.1)PyPI
Rubyrest_pki1 (latest 1.1.0)RubyGems
  • .NET has two lines of versions: 1.24.1, the last 1.x, targets .NET Framework 3.5 to 4.6 and .NET Standard 1.3 and 2.0; 2.2.0 and later target only .NET Standard 2.0, are released with Rest PKI Core and share version numbers with its client, Lacuna.RestPkiCore.Client. Both lines work with pki.rest, so choose by target framework. See .NET.
  • Java: restpki-client 1.15.9 and later are compiled for Java 8; on Java 7, use 1.15.7. See Java.
  • PHP 5.2 has no package: use the file RestPkiLegacy52.php with the Composer package educoder/pest. See PHP.
  • The REST APIs are not meant to be called directly: use a client library. API references: .NET, Java and the OpenAPI copy.

Configuration and authentication​

  • Access token: create an account at pki.rest, sign in and, on the Control Panel, click Generate new access token.
  • Client: a RestPkiClient takes the endpoint and the access token, and every starter, finisher and explorer takes the client. In direct HTTP calls, send the token in the header Authorization: Bearer <token>.
  • Endpoint: https://pki.rest/ in the cloud; Web PKI calls the alternative address https://restpki.lacunasoftware.com/ by default, which firewalls are less likely to block. On-premises, the endpoint is the address of your instance, ending in /, and the page passes it to Web PKI's init() as restPkiUrl.
  • Security context: each operation names a security context, which decides the trusted root CAs; in production the samples use StandardSecurityContexts.PkiBrazil (ICP-Brasil).
  • Licenses: the cloud service uses no license file, and Web PKI needs no license with it, even in production. An on-premises instance needs a PKI SDK license, and Web PKI then needs its own license. See Licensing.
  • Dates on PDF signatures: culture, time zone and date format come from Region and Date in your account. See Configure date and time.
var accessToken = ConfigurationManager.AppSettings["RestPkiAccessToken"];
var endpoint = ConfigurationManager.AppSettings["RestPkiEndpoint"];
if (string.IsNullOrEmpty(endpoint)) {
endpoint = "https://pki.rest/";
}
return new RestPkiClient(endpoint, accessToken);

Core operations​

The code is C# from the ASP.NET MVC samples project; the other languages follow the same flow, see Samples availability.

Sign a PDF​

PAdES signature with the user's certificate: PadesSignatureStarter.StartWithWebPkiAsync() returns the token, the page calls Web PKI's signWithRestPki({ token, thumbprint }), and PadesSignatureFinisher2.FinishAsync() returns the signed PDF and the signer's certificate. The token is not the access token and works once, so the sample sends no-cache headers. For the visual representation, see PAdES tags. See PAdES signature.

// GET action
var signatureStarter = new PadesSignatureStarter(Util.GetRestPkiClient()) {
SignaturePolicyId = StandardPadesSignaturePolicies.Basic,
SecurityContextId = Util.GetSecurityContextId()
};
signatureStarter.SetPdfToSign(userfilePath);
var token = await signatureStarter.StartWithWebPkiAsync();

// POST action, after signWithRestPki() in the browser
var signatureFinisher = new PadesSignatureFinisher2(Util.GetRestPkiClient()) {
Token = model.Token
};
var result = await signatureFinisher.FinishAsync();
var signerCert = result.Certificate;

Sign any file with CAdES​

CMS/CAdES signature of any file, stored as .p7s: CadesSignatureStarter, then CadesSignatureFinisher2 as in the PDF flow. To co-sign, call SetCmsToCoSign() with the existing CMS instead of SetFileToSign(). See CAdES signature.

var signatureStarter = new CadesSignatureStarter(Util.GetRestPkiClient()) {
SignaturePolicyId = StandardCadesSignaturePolicies.PkiBrazil.AdrBasica,
SecurityContextId = Util.GetSecurityContextId(),
EncapsulateContent = true
};
signatureStarter.SetFileToSign(userfilePath);
var token = await signatureStarter.StartWithWebPkiAsync();

Sign an XML document​

FullXmlSignatureStarter signs the whole document; XmlElementSignatureStarter with SetToSignElementId() signs one element, as in the NF-e sample. Both finish with XmlSignatureFinisher. See XML signature.

var signatureStarter = new FullXmlSignatureStarter(Util.GetRestPkiClient());
signatureStarter.SetXml(StorageMock.GetSampleXmlDocumentPath());
signatureStarter.SetSignaturePolicy(StandardXmlSignaturePolicies.XadesBes);
signatureStarter.SetSecurityContext(Util.GetSecurityContextId());
var token = await signatureStarter.StartWithWebPkiAsync();

Validate a signature​

Open a signed file and validate its signatures: PadesSignatureExplorer with Validate = true, then OpenAsync(). For CAdES use CadesSignatureExplorer, for XML XmlSignatureExplorer. See Open a PAdES signature.

var sigExplorer = new PadesSignatureExplorer(Util.GetRestPkiClient()) {
Validate = true,
DefaultSignaturePolicyId = StandardPadesSignaturePolicies.Basic,
SecurityContextId = Util.GetSecurityContextId()
};
sigExplorer.SetSignatureFile(userfilePath);
var signature = await sigExplorer.OpenAsync();

Make a printer-friendly version​

A PDF stamped with the signers and a verification code: upload the file with UploadFile(), validate it with PadesSignatureExplorer as above, then add marks with PdfMarker, built with the fluent PdfHelper; AlphaCode generates the code. See Printer-friendly version.

var client = Util.GetRestPkiClient();
var blob = client.UploadFile(pdfContent);
var pdfMarker = new PdfMarker(client);
pdfMarker.SetFile(blob);
pdfMarker.Marks.Add(manifestMark);
var result = pdfMarker.Apply();

Authenticate with a certificate​

Certificate login: GetAuthentication(), then StartWithWebPkiAsync() with the security context; after Web PKI signs the token, CompleteWithWebPkiAsync() returns the validation results. See Authentication.

// GET action
var auth = Util.GetRestPkiClient().GetAuthentication();
var token = await auth.StartWithWebPkiAsync(Util.GetSecurityContextId());

// POST action, after signWithRestPki() in the browser
var auth = Util.GetRestPkiClient().GetAuthentication();
var validationResults = await auth.CompleteWithWebPkiAsync(model.Token);
if (!validationResults.IsValid) {
return View("Failed", validationResults);
}

Request a timestamp​

ICP-Brasil timestamps with the access token as Bearer: TSP (RFC 3161) at POST https://pki.rest/tsp/a402df41-8559-47b2-a05c-be555bf66310, or REST at POST https://pki.rest/Api/TimestampPlans/a402df41-8559-47b2-a05c-be555bf66310/Issue, which returns encodedValue (the timestamp, in Base64) and info. Algorithms: SHA-1 and SHA-256. See Requesting timestamps.

{
"algorithm": "SHA256",
"value": "L80RIvFw2jwpiObzFQN+tuEQQ4E9qnGeYYYd+4DrM8M="
}

Errors​

Rest PKI answers with an HTTP status: 401 when the access token is not valid, 422 with a return code when an operation fails, and 500 for an unexpected error. See Return codes. The .NET client throws ValidationException for the error code ValidationError, whose ValidationResults say what failed, and RestPkiException for the other codes, with the code in ErrorCode. For HTTP 401 and other error statuses it throws RestErrorException, with the status in StatusCode, and when no response arrives (network failure or timeout), RestUnreachableException. All of them derive from RestException. See Errors in the .NET article. The Java client also has RestErrorException and RestUnreachableException.

ErrorWhat it means
HTTP 401The access token is not valid.
ValidationErrorThe signing certificate was not valid during the signature or authentication; the validation errors tell why, such as CertificateChainRootNotTrusted.
SecurityContextRequiredNo security context was given.
"Could not get pending signature" (in the browser)Web PKI could not reach Rest PKI. Check that the user's computer opens /Api/System/Info on the instance and, on-premises, the restPkiUrl. See the article.

Test certificates and credentials​

  • Test certificates: PKCS #12 files with password 1234, from the Lacuna Test PKI, which must never be trusted in production.
  • To accept them, use the Lacuna Test PKI security context 803517ad-3bbc-4169-b085-60053a8f6dbf. The .NET samples use StandardSecurityContexts.LacunaTest in debug builds only, and warn that an on-premises installation might not have it; the other samples use it when trustLacunaTestRoot (TRUST_LACUNA_TEST_ROOT in Python) is on in their configuration.
  • Access token: the PkiSuiteSamples projects come with a trial access token for pki.rest, with its expiry date in a comment next to it (in the ASP.NET MVC sample, RestPkiAccessToken in Web.config). For your own application, generate a token as in Configuration and authentication.

TODO(docs): no separate test environment for pki.rest is documented.

Try it​

Demos and the Rest PKI samples in each language:

View as Markdown