API reference

Key and certificate fingerprints

Fingerprint SSH keys, X.509 certificates, SPKI public keys, and OpenPGP keys.

GET POST /api/fingerprint MCP tool fingerprint

Finds every public key in input and returns its fingerprints in the formats other tools print. SSH: ssh-keygen -l SHA256 and MD5. Certificates: openssl x509 -fingerprint SHA-1 and SHA-256 over the DER, plus the RFC 7469 SPKI pin. PEM public keys: SHA-256 over the SubjectPublicKeyInfo. Where an equivalent exists, the SSH fingerprint of the same key is included, so you can confirm that a certificate and an SSH key share a key. OpenPGP: v4 (SHA-1) and v6 (SHA-256) fingerprints and key IDs for the primary key and subkeys. Private keys are refused.

Browser version (runs locally): Fingerprints.

Try it

Credentials
Remember these credentials

Not saved: you will paste them again next time.

No credentials yet? Get a client ID and secret. They are sent only to this site, in an Authorization: Basic header.

POST /api/fingerprint with a JSON body

Parameters

Parameter Type Default Description
input required string — One or more SSH public key lines, RFC 4716 blocks, PEM CERTIFICATE / PUBLIC KEY blocks, or an armored PGP public key block.

Also accepted on every endpoint: format (json | text). Parameters may come from the query string, a JSON object body, an urlencoded or multipart form, or (for input) a text/plain body.

Global parameters
Parameter Type Default Description
format json | text json json returns the documented object. text returns only the primary value as text/plain (see "Text output").

Response 200 application/json

Field Type Description
items array of one of (by kind) Keys found, in input order by format.
items[] (kind = "ssh") variant SSH public key.
items[].type string Key type, e.g. ssh-ed25519.
items[].bits integer | null Key size.
items[].comment string Trailing comment, often user@host.
items[].ssh object
items[].ssh.sha256 string SHA256: + unpadded Base64, as printed by ssh-keygen -l.
items[].ssh.md5 string MD5: + colon hex, as printed by ssh-keygen -E md5 -l.
items[] (kind = "certificate") variant X.509 certificate.
items[].subject string Subject DN.
items[].sha1 string SHA-1 of DER, colon hex.
items[].sha256 string SHA-256 of DER, colon hex.
items[].spkiSha256 string RFC 7469 pin.
items[].ssh object | null
items[].ssh.sha256 string SHA256: + unpadded Base64, as printed by ssh-keygen -l.
items[].ssh.md5 string MD5: + colon hex, as printed by ssh-keygen -E md5 -l.
items[] (kind = "public-key") variant PEM SubjectPublicKeyInfo.
items[].algorithm string Key algorithm.
items[].spkiSha256Hex string SHA-256 of the SPKI DER, colon hex.
items[].spkiSha256 string RFC 7469 pin.
items[].ssh object | null
items[].ssh.sha256 string SHA256: + unpadded Base64, as printed by ssh-keygen -l.
items[].ssh.md5 string MD5: + colon hex, as printed by ssh-keygen -E md5 -l.
items[] (kind = "pgp") variant OpenPGP public key.
items[].userIds array of string User IDs (not verified against self-signatures).
items[].keys array of object Primary key and subkeys.
items[].keys[].role "primary" | "subkey" primary or subkey.
items[].keys[].version integer Key packet version (4, 5 or 6).
items[].keys[].fingerprint string Uppercase hex fingerprint.
items[].keys[].grouped string Fingerprint in groups of four, as GnuPG prints it.
items[].keys[].keyId string Key ID: last 8 bytes (v4) or first 8 bytes (v5/v6) of the fingerprint.
items[].keys[].algorithm string Public key algorithm.
items[].keys[].bits integer | null Key size.
items[].keys[].created string Key creation time, ISO 8601.

Errors

Errors are JSON: {"error": "<message>", "code": "<code>", "param": "<name>"?}.

Status Code When
422 unprocessable_input No public key is found, a key is malformed, or the input contains a private key (which is refused without being parsed).
400 missing_parameter A required parameter is absent.
400 unknown_parameter A parameter name is not in the table above (typos are rejected, not ignored).
400 invalid_parameter A value has the wrong type, is out of range, or is not an allowed value.
413 payload_too_large The request body exceeds 1 MiB.
405 method_not_allowed A method other than GET, POST or OPTIONS.

Behaviour

  • Idempotent: the same arguments always return the same result.
  • Requires a client ID and secret (authentication). Each call is recorded as one metadata row against your client ID; inputs and outputs are never stored or logged. Responses carry cache-control: no-store.
  • CORS: any origin may call this endpoint from a browser, using your credentials.

Examples

Responses below were produced by running each request through this code at build time. Long strings are shortened.

SSH public key

curl -X POST 'https://util.caruana.me/api/fingerprint' \
  -H 'content-type: application/json' \
  -d '{"input":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGVluSiNj6bqXsllRWYUFXc2JNxW9mDP9PntMYyVHeM me@host"}'

Response 200

{
  "items": [
    {
      "kind": "ssh",
      "type": "ssh-ed25519",
      "bits": 256,
      "comment": "me@host",
      "ssh": {
        "sha256": "SHA256:z/6pzDuxOun5oze7jd1IYwPEPvElvGHF6E/heDuWjEo",
        "md5": "MD5:ed:33:28:56:1e:c6:f6:47:f4:4d:d0:da:97:32:18:ff"
      }
    }
  ]
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "fingerprint",
    "arguments": {
      "input": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGVluSiNj6bqXsllRWYUFXc2JNxW9mDP9PntMYyVHeM me@host"
    }
  }
}

OpenPGP v6 key (RFC 9580 sample)

curl -X POST 'https://util.caruana.me/api/fingerprint' \
  -H 'content-type: application/json' \
  -d '{"input":"-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf\nGwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy\nKwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw\ngyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE\nQsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn\n+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh\nBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8\nj+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805\nI8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==\n-----END PGP PUBLIC KEY BLOCK-----\n"}'

Response 200

{
  "items": [
    {
      "kind": "pgp",
      "userIds": [],
      "keys": [
        {
          "role": "primary",
          "version": 6,
          "fingerprint": "CB186C4F0609A697E4D52DFA6C722B0C1F1E27C18A56708F6525EC27BAD9ACC9",
          "keyId": "CB186C4F0609A697",
          "algorithm": "Ed25519",
          "bits": 256,
          "created": "2022-11-30T16:08:03.000Z",
          "grouped": "CB18 6C4F 0609 A697 E4D5 2DFA 6C72 2B0C 1F1E 27C1 8A56 708F 6525 EC27 BAD9 ACC9"
        },
        {
          "role": "subkey",
          "version": 6,
          "fingerprint": "12C83F1E706F6308FE151A417743A1F033790E93E9978488D1DB378DA9930885",
          "keyId": "12C83F1E706F6308",
          "algorithm": "X25519",
          "bits": 256,
          "created": "2022-11-30T16:08:03.000Z",
          "grouped": "12C8 3F1E 706F 6308 FE15 1A41 7743 A1F0 3379 0E93 E997 8488 D1DB 378D A993 0885"
        }
      ]
    }
  ]
}
Same call as an MCP tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "fingerprint",
    "arguments": {
      "input": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf\nGwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy\nKwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw\ngyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE\nQsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn\n+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh\nBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8\nj+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805\nI8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==\n-----END PGP PUBLIC KEY BLOCK-----\n"
    }
  }
}