ECDSA Sign & Verify Online — P-256 / P-384 / P-521, JWT-Compatible
Sign or verify messages with ECDSA (P-256, P-384, P-521) using PEM or JWK keys. Outputs both JOSE / P1363 (JWT-compatible) and DER (OpenSSL-compatible) signatures. 100% local via the Web Crypto API.
Last updated:
CommentsSigning and verification run entirely in your browser via the Web Crypto API. Need a fresh EC key pair? Try our ECDSA Key Generator.
Frequently Asked Questions
What's the difference between JOSE and DER signature encoding?
The math is identical — a pair of integers (r, s). The two encodings differ in how those bytes are laid out. JOSE (also called P1363, IEEE 1363) writes them as fixed-length concatenation r || s — 64 bytes for P-256, 96 for P-384, 132 for P-521. DER wraps them in an ASN.1 SEQUENCE, which is variable-length (typically 70-72 bytes for P-256). JWTs and WebCrypto default to JOSE; OpenSSL, OpenSSH, and most Go/Java crypto libraries default to DER. This tool outputs both so you can copy the one your verifier expects.
Which hash should I pair with each curve?
The JWT / NIST convention is: P-256 → SHA-256 (ES256), P-384 → SHA-384 (ES384), P-521 → SHA-512 (ES512). WebCrypto lets you mix (e.g. P-256 with SHA-384), but most verifiers don't and you'll get 'invalid signature' errors that are hard to debug. Stick with the conventional pairing unless you know the recipient supports otherwise.
Can I verify a JWT with this tool?
You can verify the signature over any arbitrary message. For a JWT, the signed message is the two base64url-encoded parts joined by a dot: header.payload. Split the JWT on the last dot: the first part is the message, the last part is the base64url signature — you'll need to convert base64url to base64 (replace - with +, _ with /, add padding = if needed) before pasting. If you just want to inspect JWT structure, our JWT Decoder does that natively.
Why does my signature verify against WebCrypto but fail in OpenSSL?
Encoding mismatch — you signed with the JOSE / P1363 format but OpenSSL expects DER (or vice versa). This tool outputs both when signing and auto-detects when verifying, but if you're passing signatures between systems, be explicit about which encoding you're using.
Are these signatures deterministic (RFC 6979)?
No — WebCrypto's ECDSA is randomized: each signature includes a fresh random nonce k. That means signing the same message twice gives you different signatures, both valid. This is the SEC1/FIPS-186 default. If you need deterministic ECDSA (RFC 6979) for reproducible signatures, use a library like noble-curves; WebCrypto doesn't expose that mode.
Related Tools
JWT Decoder
Decode JSON Web Tokens (JWT) to inspect the header, payload, and signature. Runs entirely in your browser — tokens are never sent to any server.
AES Encrypt / Decrypt
Encrypt and decrypt text with AES (128 / 192 / 256, GCM authenticated or CBC legacy) using a password. PBKDF2 key derivation with 200,000 iterations. 100% local — the Web Crypto API runs entirely in your browser.
RSA Key Generator
Generate RSA key pairs (2048, 3072, or 4096 bits) online for OAEP encryption, PSS signing, or RS256 JWTs. Exports PKCS#8 private key + SPKI public key as PEM, JWK, or DER (hex/base64). 100% local — the Web Crypto API runs in your browser, private keys never leave the tab.
Public Key Extractor
Paste an RSA or EC private key (PEM PKCS#8 or JWK) and instantly extract the matching public key in PEM (SPKI), JWK, or DER format. Perfect for publishing a JWKS endpoint, verifying a token against a private-key-only backup, or distributing a public key to peers. 100% local — the private key never leaves your browser.
RSA Encrypt / Decrypt
Encrypt text with an RSA public key or decrypt ciphertext with the private key, using RSA-OAEP (SHA-256/384/512). Accepts PEM (PKCS#8 / SPKI) or JWK. 100% local — keys and plaintext never leave your browser tab.
ECDSA Key Generator
Generate elliptic-curve key pairs (P-256, P-384, P-521) for ECDSA signatures or ECDH key agreement. Exports PKCS#8 / SPKI PEM, JWK, and DER (hex/base64). Perfect for ES256/ES384/ES512 JWTs. 100% local via the Web Crypto API — the private key never leaves your browser.