When using OAuth2 in Azure, why Certificates are more secure than using Secrets?
The Secrets have expiration and are strong, and generated automatically.
The application needs to send a JWT containing a x5t header with the thumbprint of the Certificate.
The Certificate is stored in Azure.
After OAuth2 is concluded, Azure returns a Token to the application.
If an eavesdropper steals the JWT (with the fingerprint of Certificate) isn't the same stealing the Secret?
![](../../users/profiles/164762.webp)
- 111
- 4
2 Answers
This is a slightly generic answer as I'm not super familiar with Azure in particular.
Shared secrets are worse than public key authentication in a few ways.
- They're static / persistent. If an attacker sees one once, they have it forever (until rotated). By comparison, public key auth relies on signing random and/or limited-use values (a JWT is limited-use; once it expires, there's no way to generate another without knowing the key used to sign it) so you're fine as long as the private key isn't lost. Even if the private key is lost, certificates have expiration dates and a standard revocation mechanism.
- They may be exposed to the wire, if sent directly e.g. as a Bearer token. Somebody who successfully attacks the system anywhere from your client app, through your client host, the network, the server, or the server app, can steal secrets found in the message. By comparison, private keys never leave the hardware they're generated on (which might not even be a computer, per se, but rather a hardware security module). The public key is sent over the wire, but this is not a security threat; it is, as the name says, public.
- They're known to the server. That is, the server either needs to know and store in plain text (or under reversible encryption) the actual secret if used for HMAC or similar, or can store the secret hashed but receives it in plain text (once unwrapped from TLS) with every request. Either way, an attacker who compromises the server (or in some cases just its database) gets all the secrets in active use. By comparison, with public key auth, the server (and therefore the attacker) only ever knows the public keys (not sensitive) and the values being signed (ephemeral, often single-use), not the private keys that constitute the actual persistent secret.
Note that there's a bunch of ways to use both static secrets (API keys, passwords, HMAC signing keys for JWTs or AWS SigV4, etc.) and public keys (TLS client certificates, SSH public key authentication, asymmetric digital signatures on JWTs or payloads or full messages, etc.).
Now, API keys / secrets aren't always worse in all ways. They're faster to use than digital signatures, so the latter pose a small denial-of-service risk. They are usually shorter, which saves some bandwidth. They are far more secure against some theoretical attacks like quantum computers. There are fewer "gotchas" for an implementation to get wrong.
However, when it comes to the simple question of which is a more secure method of authentication today, I'd go with public keys (whether in a certificate or not) all the way.
![](../../users/profiles/53333.webp)
- 40,303
- 3
- 74
- 98
-
thanks CBHacking, I was very brief in the question, I edited the question. – danilo Jun 10 '22 at 04:26
I Finally understand the process.
Certificates are generated by an Authority (official CAs).
Certificates can also be generated by an entity (self-signed).
The entity has data in Azure and sends the Certificates to Azure AD.
There are hardware devices that store private keys and can generate JWTs.
Daemon or Webapp must have JWTs probably generated by the entity or device.
Whoever generates JWTs needs to have the private key, so it can't be the Daemon/WebApp (the Server where it resides).
Obviously Daemon/WebApp doesn't have access to Private Key, Certificates, Data in Azure, it will request access to it.
These JWTs are short-lived.
If someone steals the JWT will have a little time to gain an Access Token.
When using Secrets the expiration time is generally much longer, and it's possible to gain access to Secrets viewing the Azure Dashboard, with Certificates it isn't possible.
![](../../users/profiles/164762.webp)
- 111
- 4