0
$\begingroup$

I want to implement authentication for an API and thought about using Shamir Secret Sharing to do so. My plan is to generate 1 Master Key which is stored in the Database, we then generate about 1000 Subkeys or more with the key threshold of 2. 1 of the subkeys is then also stored in the DB and will be used as the Application SubKey. Every user then will be provided one of the other Subkeys. If an user wants to use the API, he has to send his subkey and we combine it with our Subkey to recreate the Master Key. If the Master Key matches the Master Key from the DB, authentication completed.

Is this secure?

$\endgroup$
1
  • $\begingroup$ Just keep the Master key out of shares, then x-or it with the combined share. $\endgroup$
    – kelalaka
    Commented Sep 21, 2023 at 10:05

1 Answer 1

1
$\begingroup$

I understood your setup as follows: You have a secret master key $K$, and generate $1000$ shares $(k_1, k_2, \ldots, k_{1000})$ using a $2$-out-of-$1000$ secret sharing scheme. Each user $P_i$, as well as the API, gets one share $k_i$.

But then, any two users can combine their shares $k_i$ and $k_j$, reconstructing the master key $K$. Having done this they can e.g. generate additional shares, allowing previously unauthorized users access to the API. Mind that, by Kerckhoff's principle, parameters such as the field you are performing secret sharing over are known to an attacker.

There's also the secondary issue that this does not allow you to identify users. At some point you might want to revoke some user's access, or impose rate limits. Doing this would require keeping track of the users' shares on the server side, at which point the scheme degrades to a regular API key setup.

This seems like an XY problem. What are you trying to achieve? What prevents you from using more traditional API access control mechanisms, such as regular ('symmetric') API keys, or mechanisms such as OAuth?

If you want to avoid having to store credentials in your database, then a basic approach would be to only store hashed API keys - using a cryptographic hash function such as SHA-256 - in your database. When the server receives a request with an API key it hashes it in memory, and compares it to the hashed entry stored in the DB. This prevents leaking API keys if your DB were to be leaked.

$\endgroup$
4
  • $\begingroup$ Thank you very much. We want to save as less sensitive information in the database as possible, thats why I thought about this approach. Can they reconstruct the Master without knowing the modulo of the operation? $\endgroup$
    – Michael
    Commented Sep 21, 2023 at 8:51
  • $\begingroup$ And do you think something like Multi Signature would work? $\endgroup$
    – Michael
    Commented Sep 21, 2023 at 8:53
  • $\begingroup$ Assuming you only need API keys to establish whether a client is allowed to use the API, then a basic solution would be to store hashed API keys (using a cryptographic hash function, e.g. SHA-256) in the database. A client then includes its keys with every request (make sure to use HTTPS for the transport, of course). The server can then hash the received key in memory, and compare it with the stored version in the database. This prevents leaking API keys if your DB were to be leaked. $\endgroup$
    – Morrolan
    Commented Sep 21, 2023 at 9:21
  • $\begingroup$ I don't think multi-signatures (aka threshold signatures) are of use here. Those would be for when multiple (possibly related) users would have to authorize a single API request. Certainly you could use regular signatures (or it symmetric variant, MACs) to authorize API requests. That is done by e.g. AWS, but I would not advise doing that unless you have some of the same requirements. It rather complicates things, especially on the backend side where you then must securely store credentials. $\endgroup$
    – Morrolan
    Commented Sep 21, 2023 at 9:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.