Introduction
PKI Agent uses a REST API to communicate between the browser and the application.
The following endpoints are supported:
The following schemas define the objects used by the API:
Information about the available objects (certificates, keys).
Detailed information for a cryptographic algorithm.
Basic information representing a cryptographic algorithm.
Supported operations for the certificate or key (encrypt/decrypt/sign/verify).
Supported operations for the cryptographic algorithm (encrypt/decrypt/sign/verify).
A name-value pair that represents a property of an object or algorithm.
A collection of properties for a cryptographic algorithm.
Using the REST API
Requesting a signature with PKI Agent consists of two steps:
First, the browser should send a request to the authorization endpoint, which will prompt the PKI Agent user to grant permission. The response to that request will contain information on the certificate selected by the user, as well as an authorization token for the second request.
Second, the browser should send an HTTP POST request to the signing endpoint, containing either the data to be signed or a hash of the data. By using the token from the first request, no user interaction is required for this step.
NOTE: For any request or response that uses JSON format, all binary data should be encoded as a hexadecimal string.
Authorization
The first step in signing with the PKI Agent REST API is to make a request to the authorization endpoint, /authorize. The following JavaScript code creates and sends an authorization request:
// Create a random alphanumeric PIN to be shown to the user
const pin = randomPin();
// Display the PIN and application name to the user here
// notifypanel.innerHTML = `Your one-time authorization code is: ${pin}`;
// Send the authorization request
const authUrl = `http://127.0.0.1:9267/authorize?pin=${pin}&origin=My%20Application`;
const response = await fetch(authUrl, { method: 'GET' });
if (!response.ok) {
throw new Error("Signing request rejected. Failed to obtain authorization.");
}
// Parse the token from the response
const resp = await response.json();
var token = resp.cred;
To begin, pick a random PIN for this authorization request and display it to the user in the browser along with the name of your application. When the request is sent, PKI Agent will show the user a popup window containing the PIN and application name, so they can verify that the information matches and grant permission for signing.
The response from the authorization request will be in JSON format and contain an authorization token along with information on the selected certificate:
{
"cred": "7530726a6d396431386d31717a326977326f6f7474393271646333356f646f69",
"credtype": "Token",
"service": "",
"objects": [
{
"id": "59016E1DB603_c1d63efc135d7e14e1274aa1ba503e8107abc3aa4299585c39b4808377d6f17b",
"class": "privatekey",
"private": false,
"sensitive": false,
"exportable": false,
"readonly": false,
"group": "49440003353930313645314442363033",
"label": "Private Key 3",
"value": "",
"fingerprint": "",
"validfrom": "",
"validto": "",
"subject": "",
"friendlyname": "",
"alg": "rsa",
"algparams": [],
"size": 0,
"ops": {
"encrypt": true,
"decrypt": true,
"sign": true,
"verify": true,
"hash": false,
"signrecover": false,
"verifyrecover": false,
"wrap": false,
"unwrap": false,
"derive": false
},
"props": [
{
"prop": "publickey",
"propval": "3082020A0282020100C1...61AE6267EDE7F30203010001"
}
]
},
{
"id": "59016E1DB603_30561067f607cf21c598c8337435bfb9ef1d4fbb6334934a7c8a194f3e9ab7d0",
"class": "certificate",
"private": false,
"sensitive": false,
"exportable": false,
"readonly": false,
"group": "49440003353930313645314442363033",
"label": "Certificate 3",
"value": "30820646308204aea00302...c948a83fc0b8e47470dc95c7",
"fingerprint": "2170a80c36fcafe9b0a2f5ce150ccdd496c7203d",
"validfrom": "20230112",
"validto": "20260112",
"subject": "C=US, S=North Carolina, O=/N SOFTWARE INC., CN=/N SOFTWARE INC.",
"issuer": "C=GB, O=Sectigo Limited, CN=Sectigo Public Code Signing CA R36",
"serialno": "b090e0833143d13237e122ac8720e49d",
"friendlyname": "",
"size": 1610,
"props": []
}
]
}
Signing
The next step is to send the signing request itself to the /sign endpoint as an HTTP POST request. The request and response can use either binary or JSON data:
Option A (Binary data and response):
const signUrl = `http://127.0.0.1:9267/sign?token=${token}`;
const buf = new TextEncoder().encode("MyData");
const signResponse = await fetch(signUrl, {
method: 'POST',
headers: { "Content-Type": "application/octet-stream" },
body: buf
});
if (!signResponse.ok) {
throw new Error("Signing authorization expired or request failed.");
}
const signature = toHexString(await signResponse.arrayBuffer())
This request uses the token from the authorization response as a token query parameter. By doing so, the user does not have to grant permission through the prompt window again. The contents of the request are binary data, and the signature is returned as a binary DER signature in PKCS1 format.
Option B (JSON data and response):
const signUrl = `http://127.0.0.1:9267/sign?token=${token}&fmt=json`;
var hexEncodedData = toHexString(myData);
const buf = new TextEncoder().encode(JSON.stringify({
plaintext: hexEncodedData,
alg: {
name: "sha256WithRSAEncryption",
props: []
}
}));
const signResponse = await fetch(signUrl, {
method: 'POST',
headers: { "Content-Type": "application/octet-stream" },
body: buf
});
if (!signResponse.ok) {
throw new Error("Signing authorization expired or request failed.");
}
// Parse the signature from the response
const signResp = await signResponse.json();
const signature = signResp.signature;
This request uses the token from the authorization response as a token query parameter. By doing so, the user does not have to grant permission through the prompt window again. The plaintext field in the request body contains the binary data to be signed, converted to a hex string for transmission. The alg field can be used to specify an algorithm to use for signing.
The response will contain a hex-encoded DER signature in PKCS1 format along with information about the certificate used to create the signature:
{
"signature": "46d77d860ca5f9021f7f6b612...e32d53048d7027e980d22e85f8f",
"trace": "",
"objects": [
{
"id": "59016E1DB603_c1d63efc135d7e14e1274aa1ba503e8107abc3aa4299585c39b4808377d6f17b",
"class": "privatekey",
"private": false,
"sensitive": false,
"exportable": false,
"readonly": false,
"group": "49440003353930313645314442363033",
"label": "Private Key 3",
"value": "",
"fingerprint": "",
"validfrom": "",
"validto": "",
"subject": "",
"friendlyname": "",
"alg": "rsa",
"algparams": [],
"size": 0,
"ops": {
"encrypt": false,
"decrypt": true,
"sign": true,
"verify": false,
"hash": false,
"signrecover": false,
"verifyrecover": false,
"wrap": false,
"unwrap": false,
"derive": false
},
"props": [
{
"prop": "publickey",
"propval": "3082020A0282020100C146...267EDE7F30203010001"
}
]
},
{
"id": "59016E1DB603_30561067f607cf21c598c8337435bfb9ef1d4fbb6334934a7c8a194f3e9ab7d0",
"class": "certificate",
"private": false,
"sensitive": false,
"exportable": false,
"readonly": false,
"group": "49440003353930313645314442363033",
"label": "Certificate 3",
"value": "30820646308204aea0030201...dd1da34c948a83fc0b8e47470dc95c7",
"fingerprint": "2170a80c36fcafe9b0a2f5ce150ccdd496c7203d",
"validfrom": "20230112",
"validto": "20260112",
"subject": "C=US, S=North Carolina, O=/N SOFTWARE INC., CN=/N SOFTWARE INC.",
"issuer": "C=GB, O=Sectigo Limited, CN=Sectigo Public Code Signing CA R36",
"serialno": "b090e0833143d13237e122ac8720e49d",
"friendlyname": "",
"size": 1610,
"props": []
}
]
}
Request Authorization
GET /authorize
The client uses this endpoint to request authorization to use a certain key for a certain operation. In response, it receives the authorization credential and supplementary information about the key.
Request Query Parameters
Name | Type | Description |
---|---|---|
pin | string |
The PIN number that will be displayed to the user. |
origin | string |
The application name that will be displayed to the user. |
Responses
OK
Content-type: application/jsonProperties
Name | Type | Description |
---|---|---|
cred | string |
The authorization token. |
credtype | string |
The authorization type chosen by the server. |
service | string |
The Id of the service the authorization was given for. |
objects | CryptoObject array |
A list of objects associated with the requested authorization (certificates, keys) |
trace | string |
An optional low-level request execution trace. |
Sign Data
POST /sign
This endpoint can be used to sign data. The body of the request should include a hash of the data to be signed, either in a JSON object with other parameters or in a binary format (with other parameters in the query parameters). The signature will be returned in the body of the response.
Request Query Parameters
Name | Type | Description |
---|---|---|
token | string |
The token obtained from the authorization request. |
alg
optional |
string |
The algorithm to use for the signature. Possible values are:
|
fmt
optional |
string |
The output format to use. The default output format matches the input format (JSON in - JSON out, or octet-stream in - octet-stream out). Possible values are:
|
Request Body
Name | Type | Description |
---|---|---|
plaintext
(optional) |
string (binary) |
The data to sign. The value should contain hex-encoded binary data. |
alg
(optional) |
CryptoAlgorithm (binary) |
The algorithm to use for signing. |
Responses
A JSON object containing the DER signature encoded in hexadecimal, along with information about the associated certificate.
Content-type: application/jsonProperties
Name | Type | Description |
---|---|---|
signature | string |
The hex-encoded DER signature. |
trace | string |
An optional low-level request execution trace |
objects | CryptoObject array |
A list of objects associated with the signature (certificates, keys) |
The binary DER signature.
Content-type: application/octet-streamSchemas
CryptoObject
Information about the available objects (certificates, keys).
Name | Type | Description |
---|---|---|
id | string |
The Id of the object. |
class | string |
The type of object. |
private | boolean |
Whether the object is private. |
sensitive | boolean |
Whether the object contains sensitive data. |
exportable | boolean |
Whether the object is exportable. |
readonly | boolean |
Whether the object is read-only. |
group | string |
The group the object belongs to. |
label | string |
A lable for the object. |
value | string |
The contents of the object. |
fingerprint | string |
The object's fingerprint. |
validfrom | string |
The object's "valid from" date. |
validto | string |
The object's "valid to" date. |
subject | string |
The subject of a certificate. |
issuer | string |
The issuer of a certificate. |
serialno | string |
The serial number of a certificate. |
friendlyname | string |
The friendly name of a certificate. |
alg | string |
The algorithm for the private key (i.e. "RSA"). |
algparams | string array |
Additional parameters for the private key algorithm (i.e. "PSS"). |
size | integer |
The size of the object, in bytes. |
ops | Property |
The operations supported by the object. |
props | Property array |
An array of additional properties for the object. |
CryptoAlgorithmInfo
Detailed information for a cryptographic algorithm.
Name | Type | Description |
---|---|---|
name | string |
The name of the cryptographic algorithm. |
aliases | string array |
An array of aliases for the cryptographic algorithm. |
ops | CryptoAlgorithmOperations |
The operations supported by the cryptographic algorithm. |
props | CryptoAlgorithmProperties |
An array of properties for the algorithm. |
CryptoAlgorithm
Basic information representing a cryptographic algorithm.
Name | Type | Description |
---|---|---|
name | string |
The name of the cryptographic algorithm. Possible values are:
|
props | Property array |
An array of properties for the algorithm. |
CryptoObjectOperations
Supported operations for the certificate or key (encrypt/decrypt/sign/verify).
Name | Type | Description |
---|---|---|
encrypt | boolean |
Encrypting data. |
decrypt | boolean |
Decrypting data. |
sign | boolean |
Signing data. |
verify | boolean |
Verifying a signature. |
CryptoAlgorithmOperations
Supported operations for the cryptographic algorithm (encrypt/decrypt/sign/verify).
Name | Type | Description |
---|---|---|
encrypt | boolean |
Encrypting data. |
decrypt | boolean |
Decrypting data. |
sign | boolean |
Signing data. |
verify | boolean |
Verifying signatures. |
hash | boolean |
Generating a hash. |
signrecover | boolean |
Creating an enveloping signature. |
verifyrecover | boolean |
Verifing an enveloping signature. |
generate | boolean |
Generating a key. |
wrap | boolean |
Wrapping a key. |
unwrap | boolean |
Unwrapping a key. |
derive | boolean |
Deriving a key. |
rng | boolean |
Generating random numbers. |
Property
A name-value pair that represents a property of an object or algorithm.
Name | Type | Description |
---|---|---|
prop | string |
The name of the property |
propval | string |
The value of the property |
CryptoAlgorithmProperties
A collection of properties for a cryptographic algorithm.
Name | Type | Description |
---|---|---|
minbits | integer |
The minimum key length for the algorithm. |
maxbits | integer |
The maximum key length for the algorithm. |
oth | Property array |
An array of other properties. |