Thalhammer / jwt-cpp

A header only library for creating and validating json web tokens in c++
https://thalhammer.github.io/jwt-cpp/
MIT License
855 stars 233 forks source link

Extracting Header and Payload for external signing #279

Closed marincovic closed 9 months ago

marincovic commented 1 year ago

What's your question?

Is it possible to extract the header and payload so that I can use another library to sign?

Additional Context

Hello team,

I am new to your library so I need a bit of help. I have created a token and I have populated the header and payload. Now I wish to get the header and payload prepared for signing (base64UrlSafe(header) + '.' + base64UrlSafe(Payload)) and give it to another library for signing and then add the signature manually. Is this possible with your library and if so would you please help me with how to do it?

Thank you in advance, BR// Marin

prince-chrismc commented 1 year ago

Have you considered implementing your own algorithm? This is the class that does the signing and it's a template so you should be able to use your own implementation easily.

There's no example for this sadly but the existing implementation for RSA should give you a good idea of where to start

marincovic commented 1 year ago

In my case I am unable to get to the private key that will be used to sign. I only have a function that can be called to sign the digest. I was thinking of overloading the sign function so that we can give a pointer to a custom function. This way I think the code would be more versatile and users would not need to extend any other structures in the code itself.

If you agree I could do make a pull request and you could review my work?

BR// Marin

prince-chrismc commented 1 year ago

The libraries design is more then flexible enough 🤔 maybe an example will be helpful https://github.com/Thalhammer/jwt-cpp/blob/73f23419235661e89a304ba5ab09d6714fb8dd94/include/jwt-cpp/jwt.h#L874

struct your_algorithm{
    std::string sign(const std::string& /*unused*/, std::error_code& ec) const {
        ec.clear();
                              // CALL YOUR METHOD HERE
        return {};
    }
    void verify(const std::string& /*unused*/, const std::string& signature, std::error_code& ec) const {
        ec.clear();
        if (!signature.empty()) { ec = error::signature_verification_error::invalid_signature; }
            // CALL YOUR METHOD HERE
    }
    std::string name() const { return "your_algorithm"; }
};

Then everything else is the same.. just pass in your implementation

auto token = jwt::create()
                                  .set_id("custom-algo-example")
                                  .set_issued_at(std::chrono::system_clock::now())
                                  .set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{36000})
                                  .set_payload_claim("sample", jwt::claim(std::string{"test"}))
                                  .sign(your_algorithm{/* what ever you want */});