Live data from Hacker News

My adventure in designing API keys

vjay15.github.io

71–80 of 88 posts

Re: My adventure in designing API keys

#71
post #64
post #40

Earlier quoted context omitted.

The neat thing about JWT is that there are no secrets to scan for. Your secret material ideally lives inside an HSM and never leaves. Scanning for these private keys is a waste of energy if they were generated inside the secure context.

But JWTs are usually used as bearer tokens when doing API authentication. Those are definitely secrets that need to be scanned for. Or are you suggesting that the API requests are signed with a private key stored in an HSM, and the JWT certifies the public key? Is that common?

That's how JWT is designed to work

Re: My adventure in designing API keys

#72
post #64
post #40

Earlier quoted context omitted.

The neat thing about JWT is that there are no secrets to scan for. Your secret material ideally lives inside an HSM and never leaves. Scanning for these private keys is a waste of energy if they were generated inside the secure context.

But JWTs are usually used as bearer tokens when doing API authentication. Those are definitely secrets that need to be scanned for. Or are you suggesting that the API requests are signed with a private key stored in an HSM, and the JWT certifies the public key? Is that common?

> are you suggesting that the API requests are signed with a private key stored in an HSM, and the JWT certifies the public key? Is that common?

Very. The thing that certifies the public key is called a JWK.

https://datatracker.ietf.org/doc/html/rfc7517

This is typically hosted at a special URL that enables seamless key rotation and discovery.

https://auth0.com/docs/secure/tokens/json-web-tokens/json-we...

Re: My adventure in designing API keys

#73
post #54

Earlier quoted context omitted.

How are you storing the API key in your database?

hash of the API key just like passwords

I think they are saying passwords are salted and we use multiple rounds of hashing to prevent rainbow tables and slow down brute-forcing the password (in case of db leak). We don't need to do that for randomized long strings (like api keys), no one is guessing 32 character random string, so no salt is needed and we don't need multiple rounds of hashing.

Re: My adventure in designing API keys

#74

Earlier quoted context omitted.

The point of the checksum is to just drop obviously wrong keys. No need to handle revocation or do any DB access if checksum is incorrect, the key can just be rejected.

That sounds like it's only helpful for ddos mitigation, in which case the attacker could trivially synthesize a correct checksum.

You don't have to use a publicly documented checksum.

If you use a cryptographically secure hashing algorithm, mix in a secret salt and use a long enough checksum, attackers would find it nearly impossible to synthesise a correct checksum.

Re: My adventure in designing API keys

#75
post #74

Earlier quoted context omitted.

That sounds like it's only helpful for ddos mitigation, in which case the attacker could trivially synthesize a correct checksum.

You don't have to use a publicly documented checksum. If you use a cryptographically secure hashing algorithm, mix in a secret salt and use a long enough checksum, attackers would find it nearly impossible to synthesise a correct checksum.

I don't follow. The checksum is in "plain text" in every key. It's trivial to find the length of the checksum and the checksum is generated from the payload.

Others have pointed out that the checksum is for offline secret scanning, which makes a lot more sense to me than ddos mitigation.

Re: My adventure in designing API keys

#78
post #68

Is this running in a production environment yet? If so, do you have an email address to disclose a vulnerability?

no this is just a POC, I haven't implemented any of it

Ok, then for everyone. Don't save tokens in a database. Selects are vulnerable to timing attacks. You want a token to include a id and a signature. The ID is used to look up the scope or user attached to the token, while the signature is recreated from the ID, the server secret and some salt. The resulting signature is double checked with the provided signature with a time constant comparison.

An attacker will be able to identify valid keys, but won't be able to sign them.

You can either split the values like aws or join them with a separator.

Good idea with the slug though, makes it easier to report leaked tokens to the issuer.

Re: My adventure in designing API keys

#79

While it's true that API keys are basically prefix + base32Encode(ID + secret), you will want a few more things to make secure API keys: at least versioning and hashing metadata to avoid confused deputy attacks. Here is a detailed write-up on how to implement production API keys: https://kerkour.com/api-keys

Interesting read, I do have some questions though and hope you could answer them:

1. Why do you use the API key ID AND the organization ID, and not just one of them, to prevent the confused deputy problem?

2. Why is not necessary to use something like Argon2id for hashing? You say "our secret is already cryptograhically-secure", but what does this mean exactly? Is it due to the fact that the secret is already very high entropy and cracking it, even if we use much faster hash functions like the ones mentioned in your article, it would practically not be possible even PQ with highly parallelized hardware?

Anyways, very interesting read, thank you!

Re: My adventure in designing API keys

#80
post #49
post #15

The purpose of the checksum is to help secret scanners avoid false positives, not to optimize the (extremely rare) case where an API key has a typo

I suppose there could be two checksums, or two hashes: the public spec that can be used by API key scanners on the client side to detect leaks, and an internal hash with a secret nonce that is used to validate that the API key is potentially valid before needing to look it up in the database. That lets clients detect leaks, but malicious clients cant generate lots of valid-looking keys to spam your API endpoint and g…

That second hash is called a Message Authentication Code (MAC), it's what the JWT HS256 algorithm does
Post reply on HN