Generate SDK Signature with ASP.NET Core (C#) backend

Hello there,

With the JWT app type being deprecated soon, what is the right approach to generate the Web SDK Signature with an ASP.NET Core (C#) backend? Looking at the link below, it appears the example is using JWT.

https://marketplace.zoom.us/docs/sdk/native-sdks/web/signature/

Thank you.

Can you help confirm the correct C# function to generate SDK JWT @donte.zoom ?

you can find C# code here:

Rgds
Frederik

Thanks, but I just want to confirm with Zoom Support that the JWT token signature generation method is still valid after June 2023.

Hi @donte.zoom , I met you during Zoomtopia and had an extensive talk on this topic. Are you able to confirm that using JWT token to generate signature will still be valid after June 2023? Thanks.

Hi, @allen,

Thanks for the tags! I hope you are doing well and had a great long weekend. To answer your question, yes JWT token signature generation will be deprecated in June 2023.

JThe JWT app type (deprecated in June 2023. )

You should instead generate SDK JWT token signature with the Meeting SDK Marketplace app type. Here is our documentation on this topic:

Meeting SDK Marketplace app typ

You may also be interested in checking our JWT migration support articles:

JWT App Type Deprecation FAQ

JWT app type migration guide

Let me know if this helps to clarify or if you have any additional questions.

So what is the best way to generate the SDK app signature if my backend is asp.net core (C#)?

@allen ,

Great question! I believe you just need to create a function that handles creating the SDK JWT and endpoint that will return the token. The endpoint should be a POST and take the meeting number and role.

POST http://localhost:8080
{
“meetingNumber”: “94843468909”,
“role”: 0
}

SDK JWT consists of three parts:

  1. Header: encoded data of the token type and the algorithm used to sign the data.
{
  "alg": "HS256",
  "typ": "JWT"
}
  1. Payload: encoded data of claims intended to share.
{
  "appKey": SDK_KEY,
  "sdkKey": SDK_KEY,
  "mn": MEETING_NUMBER,
  "role": ROLE,
  "iat": 1646937553,
  "exp": 1646944753,
  "tokenExp": 1646944753
}
  1. Signature: created by signing (encoded header + encoded payload) using the SDK secret through an HMAC SHA256 algorithm.
HMACSHA256(
  base64UrlEncode(header) + '.' + base64UrlEncode(payload),
  SDK_SECRET
);

Here is our help documentation with those details for your reference :smiley:

Generate the SDK JWT

https://marketplace.zoom.us/docs/sdk/native-sdks/auth/#generate-the-sdk-jwt

Let me know if I missing anything. If so, can you share more details regarding your current implementation? This will help provide more context on what needs to be changed. In the meantime, I did some googling and found some helpful resources on generating JWT tokens.

https://www.c-sharpcorner.com/article/how-to-implement-jwt-authentication-in-web-api-using-net-6-0-asp-net-core/

Thank you for the reply. Our implementation is straightforward - we use asp.net core 6 in our backend and plain JavaScript and HTML/CSS for our front end. We will be using the Zoom Web SDK and want to generate the signature from the backend using the api key and secret and pass the signature to the front end to start the meeting.

Okay, @donte.zoom I think I see what you have here is for Node.js. That is fine because we have an app using Node.js and there is a GitHub example repo, but for our other app, which is asp.net Core MVC, again, we just want to confirm that this method will still work after 2023 since it is using jwt token, as long as we swap out the API Key and Secret using the SDK Key and Secret?

Link - https://marketplace.zoom.us/docs/sdk/native-sdks/web/signature/#sdk-app-type

// this demo use vscode and .NET Core 2.2.5
// https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code
// https://dotnet.microsoft.com/download
// dotnet add package Microsoft.IdentityModel.Tokens
// dotnet add package System.IdentityModel.Tokens.Jwt
// https://www.red-gate.com/simple-talk/dotnet/net-development/jwt-authentication-microservices-net/
// https://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/#csharp
// https://marketplace.zoom.us/docs/sdk/native-sdks/Web-Client-SDK/tutorial/generate-signature
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.IdentityModel.Tokens;
namespace Zoom {
    class Program {
        static readonly char[] padding = { '=' };
        static void Main (string[] args) {
            Console.WriteLine ("Zoom copyright!");
            Console.WriteLine ("generate websdk token!");
            string apiKey = "apiKey";
            string apiSecret = "apiSecret";
            string meetingNumber = "";
            String ts = (ToTimestamp(DateTime.UtcNow.ToUniversalTime()) - 30000).ToString();
            string role = "1";
            string token = GenerateToken (apiKey, apiSecret, meetingNumber, ts, role);
            Console.WriteLine (token);
        }
        public static long ToTimestamp (DateTime value) {
            long epoch = (value.Ticks - 621355968000000000) / 10000;
            return epoch;
        }
        public static string GenerateToken (string apiKey, string apiSecret, string meetingNumber, string ts, string role) {
            string message = String.Format ("{0}{1}{2}{3}", apiKey, meetingNumber, ts, role);
            apiSecret = apiSecret ?? "";
            var encoding = new System.Text.ASCIIEncoding ();
            byte[] keyByte = encoding.GetBytes (apiSecret);
            byte[] messageBytesTest = encoding.GetBytes (message);
            string msgHashPreHmac = System.Convert.ToBase64String (messageBytesTest);
            byte[] messageBytes = encoding.GetBytes (msgHashPreHmac);
            using (var hmacsha256 = new HMACSHA256 (keyByte)) {
                byte[] hashmessage = hmacsha256.ComputeHash (messageBytes);
                string msgHash = System.Convert.ToBase64String (hashmessage);
                string token = String.Format ("{0}.{1}.{2}.{3}.{4}", apiKey, meetingNumber, ts, role, msgHash);
                var tokenBytes = System.Text.Encoding.UTF8.GetBytes (token);
                return System.Convert.ToBase64String (tokenBytes).TrimEnd (padding);
            }
        }
    }
}

@allen,

The method looks good, but I’d recommend testing it to be sure. All you would have to do is:

  1. Swap out the values API Key and Secret - for - the SDK Key and Secret

  2. Run the code to generate the signature

  3. Then verify it by using the signature to Auth the SDK

  4. You can also decode the signature with JWT.io to confirm as well

I see you mentioned our Sample Signature Node.js so I’m linking it below in case anyone else is interested in taking a look at the implementation.

Zoom Meeting SDK Sample Signature Node.js

@donte.zoom

Unfortunately, I did a test using the Meeting SDK Web Sample and got an invalid signature error. I entered the signature to jwt.io and it was an invalid signature.

for the current Meeting SDK Web Sample you need Meeting SDK App

what is the status of your Meeting SDK app - activated?

b127cfc3fccc53582915269b76f9a112ed81ee76

Definitely activated. It is the sample I pulled from Zoom GitHub here - https://github.com/zoom/meetingsdk-web-sample

I had it working before using the SDK Key and Secret. Now I replaced the lines in index.js -

//meetingConfig.signature = res.result;
meetingConfig.signature = “ABC”;

with the generated signature, and it doesn’t work.

@allen,

Did some testing on my side with C# and I can confirm the following script works as expected with the Web SDK.

using System;
using System.Collections.Generic;
using System.Text;
using Jose;


  public class ZoomHelper
  {
      static readonly string sdkKey = "ENTTER YOUR SDK KEY";
      static readonly string sdkSecret = "ENTTER YOUR SDK Secret";
      static readonly int roleId = 1; // 0 for participant, 1 for host
      private static long ToEpoch(DateTime value) => (value.Ticks - 621355968000000000) / (10000 * 1000);
      public static string GetSignature(long meetingNumber)
      {
          var now = DateTime.UtcNow;
          var iat = ToEpoch(now);
          var exp = ToEpoch(now.AddDays(1));
          var payload = new Dictionary<string, object>()
          {
              { "appKey", sdkKey },
              { "sdkKey", sdkKey },
              { "mn", meetingNumber },
              { "role", roleId },
              { "iat", iat },
              { "exp", exp },
              { "tokenExp", exp },
          };
          return Jose.JWT.Encode(payload, Encoding.UTF8.GetBytes(sdkSecret), JwsAlgorithm.HS256);
      }
  }

For context, I grab the code snippet from the link below and generated it using a simple C# console app with VScode. :

That aside, I am working on what will either be a demo app or blog on generating the Web SDK Signature with an ASP.NET Core (C#) backend. Still getting familiar with C# so I will need a little time. In the meantime, feel free to tag me here for updates on that project.

1 Like

Awesome! I tested this, and it works! Thank you so much for the help. I will keep an eye out for your demo app.

Phenomenal – super glad to hear you are up and going, @allen! Should you have any additional questions, please feel free to let us know!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.