Перейти к содержимому
ecdsa.com

Certificates

Decode an X.509 certificate or chain

POSThttps://ecdsa.com/api/v1/cert/decode

Accepts PEM (one or more CERTIFICATE blocks — a whole chain works) or a single DER certificate as base64/hex. Returns a structured summary per certificate — subject, issuer, validity, key and signature algorithms, SAN, key usage, fingerprint — plus assessments (weak hashes, expiry, CA/Browser Forum lifetime limits, post-quantum notes).

API-ключ
Необязателен; ключу нужна область доступа api
Расход квоты при вызове с ключом
1 единица за вызов
Лимит запросов
60 запросов в минуту с одного IP

Запрос

Тело запроса (JSON): CertDecodeRequest

ПолеТипОбязательноеОписание
certificatestringда

PEM with one or more CERTIFICATE blocks (chains welcome), or one DER certificate as base64/hex.

Ответы

200Decoded certificates with assessments.

ПолеТипОбязательноеОписание
certificatesCertificateSummary[]да
notesstring[]да

Per-block problems and skipped-block notes.

Заголовки: X-Request-Id · X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset · X-Quota-Limit · X-Quota-Remaining · X-Quota-Reset

СтатусЗначениеКоды
400Bad request. Input limits: a request body of at most 100 KB (a larger one is answered with 413) and arrays and objects nested at most 64 levels deep, JSON documents inside string fields included.
401Unauthorized.
403Forbidden.
404Not found.
405Method not allowed.
413Payload too large.
429Too many requests.
500Internal server error.
503Service unavailable.
504Gateway timeout.

Каждый ответ с ошибкой содержит JSON-объект ошибки; что означает каждый код и что с ним делать, сказано в таблице ошибок.

Пример

A self-signed ECDSA P-256 certificate

curl
curl -sS 'https://ecdsa.com/api/v1/cert/decode' \
  -H 'content-type: application/json' \
  -d '{
  "certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----"
}'
JavaScript (fetch)
const response = await fetch("https://ecdsa.com/api/v1/cert/decode", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    "certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----"
  }),
});
console.log(response.status, await response.json());
Python (httpx)
import httpx

response = httpx.post(
    "https://ecdsa.com/api/v1/cert/decode",
    json={
        "certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----",
    },
    timeout=30.0,
)
print(response.status_code, response.json())
Ответ 200
{
  "certificates": [
    {
      "subject": "CN=demo.ecdsa.com, O=ECDSA.com Signature Lab, C=US",
      "issuer": "CN=demo.ecdsa.com, O=ECDSA.com Signature Lab, C=US",
      "selfSigned": true,
      "serialNumber": "04:a1:b2:c3:d4:e5:f6:07",
      "version": 3,
      "notBefore": "2026-01-15T00:00:00.000Z",
      "notAfter": "2027-01-15T00:00:00.000Z",
      "validityStatus": "valid",
      "daysRemaining": 87,
      "lifetimeDays": 365,
      "publicKeyLabel": "ECDSA P-256",
      "signatureLabel": "ecdsa-with-SHA256",
      "san": [
        "DNS:demo.ecdsa.com",
        "DNS:www.demo.ecdsa.com"
      ],
      "keyUsage": [
        "digitalSignature"
      ],
      "extendedKeyUsage": [
        "serverAuth",
        "clientAuth"
      ],
      "basicConstraints": {
        "ca": false
      },
      "subjectKeyId": "e9:10:bd:14:b6:ed:51:f2:ac:c7:67:d2:16:0b:65:8f:ef:cf:65:a9",
      "authorityKeyId": null,
      "fingerprintSha256": "54:7A:73:8B:31:CE:3A:55:54:58:4B:5C:FD:D8:CE:7F:78:B7:05:15:29:A3:B7:D5:38:FA:3D:A7:93:5E:C2:CA",
      "assessments": [
        {
          "kind": "info",
          "title": "Classical algorithm — post-quantum migration ahead",
          "body": "ECDSA P-256 (≈128-bit classical security) is a sound choice today. It is, however, quantum-vulnerable: NIST IR 8547 (draft) plans to disallow classical signature algorithms — ECDSA, EdDSA and RSA — after 2035. At this key size there is no earlier 2030 milestone — that step applies only to 112-bit parameter sets such as RSA-2048. No emergency — but worth an inventory: our upcoming repository scanner maps where your systems still sign with classical algorithms and the matching post-quantum migration targets."
        },
        {
          "kind": "ok",
          "title": "Within validity period",
          "body": "Valid until 2027-01-15 00:00:00 UTC — 87 days remaining."
        }
      ]
    }
  ],
  "notes": []
}

Ответ API на этот пример, полученный для этой страницы 20 октября 2026 г.; относительное время и количество дней в нём отсчитываются от этого дня.

Коды ошибок

КодСтатусЗначение
invalid_json400The body is not valid JSON or not a JSON object; or the input nests arrays and objects more than 64 levels deep (JSON documents inside string fields count too), or is too complex to inspect for private keys.
missing_field400A required field is absent or empty.
invalid_input400A field could not be parsed — the message explains exactly why.
private_key_rejected400The request contains private-key material (a PEM PRIVATE KEY block, an OpenSSH, SSH2 or PuTTY private key, or a JWK with "d"). Never send private keys anywhere.
unauthorized401The Authorization or X-API-Key header is malformed, the API key is not valid (wrong checksum, unknown, revoked or expired), or the operation needs a key.
forbidden_scope403The API key is valid but lacks a scope this operation requires; the message names it.
not_found404No operation exists at this path.
method_not_allowed405The path exists but does not accept this HTTP method; see the Allow header.
payload_too_large413The body exceeds 100 KB.
rate_limited429Too many requests — see Retry-After.
quota_exceeded429A daily or monthly quota of the API key's account is used up. X-Quota-Reset (and Retry-After) say when it starts over; retrying earlier cannot succeed.
internal_error500Unexpected server error.
service_unavailable503API keys cannot be verified right now (the key store is unreachable); retry shortly.
timeout504The operation did not finish within its time budget.

Схемы

CertificateSummary

ПолеТипОбязательноеОписание
subjectstringда
issuerstringда
selfSignedbooleanда

Subject and issuer are identical.

serialNumberstringда

Colon-separated hex.

versioninteger | nullда
notBeforestringда
  • формат date-time
notAfterstringда
  • формат date-time
validityStatusstringда
  • одно из значений "valid", "expiring", "expired" или "not-yet-valid"
daysRemainingintegerда

Days until notAfter (zero or negative once expired).

lifetimeDaysintegerда
publicKeyLabelstringда
signatureLabelstringда
sanstring[]да

"DNS:example.com" style Subject Alternative Name entries.

keyUsagestring[]да
extendedKeyUsagestring[]да
basicConstraintsobject | nullда
basicConstraints.cabooleanда
basicConstraints.pathLengthintegerнет
subjectKeyIdstring | nullда
authorityKeyIdstring | nullда
fingerprintSha256stringда

Colon-separated uppercase hex SHA-256 of the DER.

assessmentsCertificateAssessment[]да

CertificateAssessment

ПолеТипОбязательноеОписание
kindstringда
  • одно из значений "ok", "err", "warn" или "info"
titlestringда
bodystringда

Error

The error envelope of every non-2xx response.

ПолеТипОбязательноеОписание
errorobjectда
error.codestringда

Machine-readable error code. Each response lists the codes it can carry; new codes may be added within v1, so treat an unknown code by its HTTP status.

error.messagestringда

Human-readable explanation (English).

error.requestIdstringнет

The X-Request-Id of this request — quote it when reporting a problem. Sent since v1.1.

error.detailobjectнет

Structured context for the error, such as the offending field; omitted when there is none.

  • поля с любыми именами
error.docsstringнет

Where the error codes are explained. Sent since v1.1.

  • формат uri

Все операции перечислены в справочнике API.