ECDSA sign

Sign a message with your ECDSA private key — NIST P-256 or P-384, DER or raw r||s — and get a base64/hex signature. Deterministic (RFC-6979). Runs in your browser; the key never leaves your device.

Signature

About this tool

ECDSA Sign signs a message with an elliptic-curve private key and returns the signature in base64 and hex. Paste your PEM key, pick the curve and output format, and sign — entirely in your browser via WebAssembly. Your key and message are never uploaded.

Options

Deterministic signatures

Signing uses RFC-6979 deterministic nonces, so signing the same message with the same key always yields the same signature — no randomness required, and no risk of a repeated-nonce key leak.

Key format

The key must be PEM-encoded PKCS#8 (-----BEGIN PRIVATE KEY-----). To generate one:

openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256

If you have an old-style SEC1 key (-----BEGIN EC PRIVATE KEY-----), convert it:

openssl pkcs8 -topk8 -nocrypt -in sec1.pem

Verify a signature with the matching public key using your standard ECDSA tooling (OpenSSL, WebCrypto, JOSE libraries).

FAQ

Why do I get the same signature every time I sign?

That's by design: the tool uses RFC-6979 deterministic nonces, so a given key + message always produces the same signature. It still verifies exactly like a randomized ECDSA signature — determinism just removes the repeated-nonce risk.

Which format do I need for a JWT (ES256/ES384)?

Choose raw. JOSE/JWT and WebCrypto expect the fixed-length r || s encoding — 64 bytes for P-256 (ES256), 96 bytes for P-384 (ES384). DER is the ASN.1 form OpenSSL and X.509/TLS tooling use; the two are not interchangeable.

It says "invalid EC private key" — what's wrong?

The key must be PEM PKCS#8 (-----BEGIN PRIVATE KEY-----) and its curve must match the one you selected — a P-384 key won't parse when the curve is set to P-256. If your file says BEGIN EC PRIVATE KEY (SEC1), convert it first with openssl pkcs8 -topk8 -nocrypt.

Is P-521 or Ed25519 supported?

No — this tool signs with NIST P-256 and P-384 only (the curve fixes the hash: SHA-256 or SHA-384). Ed25519 is a different signature scheme (EdDSA), not ECDSA.

Does my private key leave the browser?

No. Signing runs locally in WebAssembly; the key and message are never sent to a server. Still, treat any pasted production key with care and prefer test keys where possible.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool ecdsa-sign "The message to sign" 'private_key=-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/ecdsa-sign/?message=The%20message%20to%20sign&private_key=-----BEGIN%20PRIVATE%20KEY-----%0A...%0A-----END%20PRIVATE%20KEY-----&curve=p256&format=der

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.