Tutorial: Sign Code Using the Demo Server¶
This tutorial shows how to sign code using the Cryptera Keyserver trial environment.
You will authenticate as a client, request a signing operation, obtain approval, and retrieve a valid signature.
The tutorial uses: - The REST API - Example users and keys available on the trial server - Standard command-line tools: curl, jq, openssl, and g++ (can be omitted)
This tutorial is intended for new users and CI/CD engineers who want to understand the complete signing workflow.
Uses Internal Authserver
This tutorial uses the Keyserver’s built-in internal Authserver for demonstration purposes only.
Do not use the internal Authserver in production.
Production deployments must authenticate using an external OAuth2/OIDC provider such as
Azure Entra ID, GitLab OIDC, GitHub Actions OIDC, or Keycloak.
Trial vs Production Authentication
The internal Authserver is intended for evaluation and testing only.
Production environments must rely on an external identity provider.
Prerequisites¶
This tutorial assumes:
- While most Linux distributions should work, this tutorial is based on Ubuntu 24.04
- You have the following tools installed:
Replace apt with your platform's package manager if needed.
Environment Setup¶
Set the base URLs for your trial server:
export KEYSERVER="https://keyserver.<UNIQUE-ID>.cryptera-security.io"
export AUTHSERVER="https://authserver.<UNIQUE-ID>.cryptera-security.io/oauth2/token"
Step 1: Authenticate as a Client¶
In this tutorial, you will authenticate as fw-client, a client subject allowed to request signing operations. The trial environment uses same predefined password for all users, refer to your getting started email.
Create a Base64-encoded credential string:
Request an OAuth2 access token:
export TOKEN=$(
curl -sS --tlsv1.3 \
-X POST \
-H "Authorization: Basic $AUTH_CREDS" \
-d "grant_type=client_credentials" \
$AUTHSERVER | jq -r .access_token
)
Verify:
If the token prints, authentication succeeded.
Step 2: Choose a Key for Signing¶
The trial server provides several predefined signing keys.
You can view and manage these keys at Signing Key Admin.
For demonstration, four preconfigured keys are available:
| Key | Algorithm | Hash | Approvers Required |
|---|---|---|---|
| key1 | ECDSA | SHA256 | 0 |
| key2 | ECDSA | SHA384 | 1 |
| key3 | ECDSA | SHA512 | 2 |
| key4 | RSA | SHA256 | 1 |
For this tutorial, we use key2, which requires one approver.
This demonstrates the approval workflow clearly.
Set environment variables:
Step 3: Retrieve the Public Certificate (Optional but Recommended)¶
Fetching the certificate allows you to verify the signature later.
curl -sS --tlsv1.3 \
-H "Authorization: Bearer $TOKEN" \
"$KEYSERVER/api/keys/$KEYID" | jq -r .certificate \
> certificate.pem
Step 4: Build and Hash a Test Binary¶
Create a simple C program:
Compile it:
Hash the binary using the required algorithm:
Step 5: Request a Signing Operation¶
A signing operation defines:
- Which key will be used
- How many times the key may be used
- How long the operation is valid
- A human-readable description
Request an operation:
export OPERATION_ID=$(
curl -sS --tlsv1.3 \
-X POST "$KEYSERVER/api/operations" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"validms": 60000,
"description": "Signing Hello World example binary",
"new-keyusagerestrictions": [
{ "keyid": "'"$KEYID"'", "maxusagecount": 1 }
]
}' | jq -r .id
)
Verify:
This operation now awaits approval.
Step 6: Approve the Operation (via the UI)¶
- Open your browser.
- Navigate to:
https://keyclient.<UNIQUE-ID>.cryptera-security.io/approvaladmin - Log in as an approver, e.g.:
- Locate the pending operation with your
OPERATION_ID. - Review the details.
- Click Approve.
Once approved, the operation becomes active.
Step 7: Request the Signature¶
With the operation now approved, request the signature:
export SIGNATURE=$(
curl -sS --tlsv1.3 \
-X POST "$KEYSERVER/api/signorders" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationid": "'"$OPERATION_ID"'",
"keyid": "'"$KEYID"'",
"inputdata": "'"$HASH_TO_SIGN"'",
"inputformat": "hex",
"inputpadding": "none",
"signatureformat": "asn1",
"description": "Hello World example signing"
}' | jq -r .result
)
Print the signature:
This value is ASN.1-encoded and hex-formatted.
Step 8: Verify the Signature¶
Convert the signature to binary:
Extract public key from certificate:
Verify:
Expected output:
Step 9: Modify Binary to fail verification¶
To trigger a failed verification step, the binary can be modify to no longer match what was signed.
Modify the program:
Compile it:
And try to verify again:
Completion¶
You have now:
- Authenticated as a Keyserver client
- Requested an operation using a key requiring approval
- Approved the operation via the UI
- Performed a signing operation using the REST API
- Verified the resulting signature using OpenSSL
This completes the basic signing workflow and establishes the foundation for integrating signing into CI/CD systems.