Hi, [email protected]. I’m curious about zero-knowledge encryption, and I would like to use it in my CS50x final project. My goal is to authenticate users and store their encrypted data on the server so that only the users can decrypt it.

I understand the general concepts of public and private keys, as well as symmetric keys, and how to use them to protect data. However, I don’t understand how to authenticate users. I have searched online for information on implementing the zero proof knowledge authentication flow, but I found either vague high-level descriptions or research papers that require a strong background in mathematics and cryptography to understand and implement.

Could you maybe suggest some resources on this topic? When your search for “how to implement jwt authentication”, you can find many articles that describe the flow with code examples. I’m looking for something similar.

Or should I choose a simpler project?

  • hallettj@leminal.space
    link
    fedilink
    English
    arrow-up
    1
    ·
    2 hours ago

    It seems to me that you’re asking about two different things: zero-knowledge authentication, and public key authentication. I think you’d have a much easier time using public key auth. And tbh I don’t know anything about the zero-knowledge stuff. I don’t know what reading resources to point to, so I’ll try to provide a little clarifying background instead.

    The simplest way to a authenticate a user if you have their public key is probably to require every request to be signed with that key. The server gets the request, verifies the signature, and that’s it, that’s an authenticated request. Although adding a nonce to the signed content would be a good idea if replay attacks might be a problem.

    If you want to be properly standards-compliant you want a standard “envelope” for signed requests. Personally I would use the multipart/signed MIME type since that is a ready-made, standardized format that is about as simple as it gets.

    You mentioned JSON Web Tokens (JWTs) which are a similar idea. That’s a format that you might think you could use for signing requests - it’s sort of another quasi-standardized envelope format for signed data. But the wrinkle is that JWTs aren’t used to sign arbitrary data. The data is expected to be a set of “claims”. A JWT is a JSON header, JSON claims, and a signature all of three which are serialized with base64 and concatenated. Usually you would put a JWT in the Authorization header of an HTTP request like this:

    Authorization: Bearer $jwt
    

    Then the server verifies the JWT signature, inspects the “claims”, and decides whether the request is authorized based on whether it has the right claims. JWTs make sense if you want an authentication token that is separate from the request body. They are more complicated than multipart/signed content since the purpose is to standardize a narrow use case, but to also support all of the features that the stakeholders wanted.

    Another commenter suggested Diffie-Hellman key exchange which I think is not a bad idea as a third alternative if you want to establish sessions. Diffie-Hellman used in every https connection to establish a session key. In https the session key is used for symmetric encryption of all subsequent traffic over that connection. But the session key doesn’t have to be an encryption key - you could use the key exchange to establish a session password. You could use that temporary password to authenticate all requests in that session. I do know of an intro video for Diffie-Hellman: https://youtu.be/Ex_ObHVftDg

    The first two options I suggested require the server to have user public keys for each account. The Diffie-Hellman option also requires users to have the server’s public key available. An advantage is that Diffie-Hellman authenticates both parties to each other so users know they can trust the server. But if your server uses https you’ll get server authentication anyway during the connection key exchange. And the Diffie-Hellman session password needs an encrypted connection to be secure. The JWT option would probably also need an encrypted connection.

  • FizzyOrange@programming.dev
    link
    fedilink
    arrow-up
    14
    ·
    5 hours ago

    So… to store encrypted data that only the user can decrypt you don’t need any fancy zero knowledge algorithms. Just have the user keep the encryption key.

    For authentication you could use one of these algorithms. OPAQUE seems to be popular. I’m not an expert but it seems like it has several neat zero-knowledge style properties.

    But probably forget about implementing it without a strong background in cryptography.

  • epyon22@programming.dev
    link
    fedilink
    arrow-up
    8
    arrow-down
    2
    ·
    6 hours ago

    I believe I understand what you want. “Zero” login. So when a user comes to your site or first boots up your app a private key gets generated locally. It will then do a handshake with the server, where that the server understands that these encrypted messages are from this user, this uniquely identifies the user, and also can be used for e2e.

    Reference https://dev.to/spalladino/a-beginners-intro-to-coding-zero-knowledge-proofs-c56

  • MajorHavoc@programming.dev
    link
    fedilink
    arrow-up
    1
    ·
    5 hours ago

    research papers that require a strong background in mathematics and cryptography to understand and implement.

    Lol. I guess that makes sense. Outside of school, we hope that all authentication will be implemented only cryptography experts anyway.

    Could you maybe suggest some resources on this topic?

    Not really, sorry. I’m not aware of anyone creating resources for your situation.

    Or should I choose a simpler project?

    For some context, cryptography isn’t even usually implemented “completely correctly” by experts. That’s part of why we have constant software security patches.

    If I were in your shoes, I guess it would depend on my instructor and advisors.

    If I felt like they have the skills to catch mistakes and no time to help correct mistakes, then I would just choose a simpler project. If they’re cool with awarding a good grade for a functional demo, I might just go for it.

    I guess I would take this one to an advisor and get some feedback on practicality.