How to configure different Keys for Consumer & Apigee while encrypting JWT Token?

We have developed a API proxy where response is a JWT Token (payload is passed in JWT). Currently it is encrypted with a key saved in KVM.

For the caller to decrypt the token we have to share the Key with them (which they will use in the end and will never transfer over network)

But it still has issue as the someone might get the key from caller's code or the caller gives it to someone.

How to have different Key for APIGEE & the caller and still do the data exchange (Like done in Diffie Helman Algorithm) where both sides have different private key?

2 1 506
1 REPLY 1

Currently it is encrypted with a key saved in KVM.

By "encrypted" do you mean "signed"? There is such a thing as "encrypted JWT" but currently there is no builtin policy in Apigee Edge that allows generation of an encrypted JWT. I'll assume "signed" for the remainder of my response. If that's a bad assumption, please correct me.

For the caller to decrypt the token we have to share the Key with them (which they will use in the end and will never transfer over network)

I guess then you are using a symmetric algorithm? For a receiver of a JWT that has been signed with a symmetric algorithm (HS256, HS384, HS512), the receiver must possess the same key that was used to produce the signature (Really it's an HMAC; some people get pedantic about the differences between HMAC and Signature).

You may know that if you use an asymmetric algorithm, like RS(256,384,512) or PS(256,384,512) or ES(256,384,512) then it's not necessary to share a secret key to allow a peer to verify a signature on the JWT. Instead you share a public key, which is not a secret at all. It's "public"!!

Most people don't rely on the symmetric algorithms, because of the key management issues. BUT, with Apigee Edge, each client app gets a client secret, and you could use *that* as the secret key to sign the JWT. The client presumably obtains that secret via download from the develpoer portal, which is done over HTTPS (Secure).

But it still has issue as the someone might get the key from caller's code or the caller gives it to someone.

Yes, exactly right. That is the problem with symmetric encryption: key management. You need to store the secret somewhere. If you put it into the client, then any party that has access to the client effectively has access to the secret. For example if it's an app that runs on a mobile phone, then the secret is not a secret, is it? A sufficiently determined developer could decompile your mobile app code and view the secret.

How to have different Key for APIGEE & the caller and still do the data exchange (Like done in Diffie Helman Algorithm) where both sides have different private key?

Asymmetric algorithms, the ones I mentioned above, rely on Public/private keys. The signer signs using a private key which is kept securely on the signer's system. This works for a server or cloud app, which runs on a system that is physically secure. Not accessible except by authorized operators. The receiver or verifier of the JWT needs only the public key. Often the public key that corresponds to a private key is distributed and asserted via a Certificate, which... is just a digital document signed by another trusted party (like Verisign, or Entrust, or GoDaddy, etc) that asserts "this public key belongs to the entity known as api.mycompany.com". So then the verifier can

  1. obtain the JWT
  2. separately, obtain the certificate for the signer
  3. verify that the certificate is valid (not expired, signed by a trusted third party)
  4. verify that the cert belongs to the expected party (it's a cert for mycompany.com, and not a cert for hackers-r-us.com)
  5. extract the public key from the certificate
  6. verify the signature on the JWT using the public key

You can do this in the client using an appropriate JWT client-side library for your client platform. Java, C#, nodejs, python, golang,.. they all have JWT and Cert libraries that allow you to do what I just described.

You don't need to go to the extent of using a Certificate. The Cert is a "flourish" on the basic model, which is public/private key signing. In the simpler approach, the client (verifier) just "has" a public key for the signer. This is often distributed via a public URL, and there's even a standard for doing that: the JWK standard. An example JWKS endpoint is here. In this model the verifier trusts that the JWKS endpoint for an issuer is valid, and can rely on the public keys asserted there. Google, Microsoft, Salesforce, Auth0, ... most well known issuers of JWT use this approach to distribute public keys.

the approach with just public keys might be:

  1. obtain the JWT
  2. separately, obtain the trusted public key for the signer from the JWKS endpoint
  3. verify the signature on the JWT using the public key

Client libraries will probably also support the use of these JWKS endpoints.

Apigee can generate or verify JWT using either symmetric or asymmetric algorithms. As you can see the asymmetric algorithms simply key management in some cases.

Now if you really ARE talking about encrypted JWT, and not signed JWT, it's a different conversation. I can explain that too, but I won't unless it's necessary. Let me know.