Secrets and key pairs
What a credential is
Proofing linked Alex's portal account to the right patient record. The clinic does not want to repeat that process every time Alex checks a result, so the account needs something Alex can present on each return. The portal is not the only party in this position. Behind the scenes, the portal's server fetches results from an outside laboratory's API, and the lab needs to know that each request really comes from the clinic.
A credential is evidence that a person or application presents to show it is the party an account or relationship belongs to. Alex might use a password or a passkey. The portal's server might use a client secret, a private key, or a certificate.
A credential is different from an identifier. Alex's email address says which account is being claimed; the password supports the claim. The portal's client ID tells the lab which client is calling; the client secret or key is what the lab checks. Identifiers can be known by many people. A credential is only useful as evidence if its holder can keep it from others.
Credentials fall into two broad families, and the difference between them shapes much of what follows in this series.
Key pairs
Public-key cryptography splits that capability in two. A key pair is a private key and a public key generated together and mathematically related. The private key can create a signature. The public key can check that signature but cannot create one, and the private key cannot practically be worked out from it.
The clinic keeps its private key to itself and gives the lab the public key. Now the lab can check that a request was signed by the clinic, but a thief who steals the lab's copy of the public key gains nothing they could not already find. The same public key can be given to any number of verifiers without adding risk.
# Shared key: both sides can create and check the same tag
# Portal
tag = hmac_sha256(shared_key, request)
# Lab
accepted = constant_time_equal(received_tag, hmac_sha256(shared_key, received_request))
# Key pair: only the private key can sign
# Portal
signature = sign(clinic_private_key, request)
# Lab
accepted = verify(clinic_public_key, received_request, received_signature)
Key pairs can also protect confidentiality: data encrypted with a public key can be decrypted only with the matching private key. In practice, public-key operations are much slower than shared-key ones, so protocols such as TLS use key pairs to authenticate and agree on fresh shared keys, then use those shared keys to protect the rest of the connection.
Alex's passkey from Security keys, passkeys, and biometrics is a key pair too. The portal stores only the public key, so a breach of the portal's database does not reveal anything that could sign in as Alex.
| Question | Shared secret | Key pair |
|---|---|---|
| Who can create a valid proof? | Everyone holding the secret, including the verifier | Only the private key holder |
| What does the verifier store? | The secret, or a hash when the secret is a password | The public key, which is not secret |
| What if the verifier's copy leaks? | The attacker may be able to impersonate the holder | The attacker can verify signatures, nothing more |
| How many verifiers can share it? | Ideally one per secret | Any number |
Proving possession
A signature over a fixed message has a weakness: if an attacker records it, they can send the same signed message again. To show that the key holder is present now, a verifier can issue a challenge, a random value it has never used before. The holder signs the challenge, and the verifier checks the signature with the public key. Because each challenge is fresh, an old answer is useless.
That is the core of passkey sign-in, and of how a TLS server proves it holds the private key for its certificate. The key itself never leaves its holder.
Many credentials work differently. A bearer credential, such as an API key sent with each request or an ordinary access token, is accepted from whoever presents it. Proof-of-possession designs bind a credential to a key so that a copied token is not enough on its own. The Advanced OAuth lessons on DPoP and mutual TLS show how that binding works for access tokens.
Whose key is it?
A public key on its own is just a long number. Before trusting a signature, the lab needs to know that this public key belongs to the clinic, not to someone who sent the lab their own key while claiming to be the clinic.
For a small number of partners, the answer can come from setup: the clinic hands the lab its public key through a channel the lab already trusts, and the lab records it against the clinic's registration. At the scale of the web, where a browser meets millions of servers it has never seen, that does not work. Certificates solve that problem, and they are the subject of What a certificate says. First, Digital signatures looks more closely at what a signature proves once the right key is known.