Client SDK Invalid Signature errorCode:200 PHP

Hello Everybody


Description
I need to update a JWT app to SDK meetings app before deprecation.
I did create a new SDK app from Marketplace and I got a new Client Id and Client secret to use.
Following the instructions on:
https://marketplace.zoom.us/docs/guides/build/jwt-app/jwt-app-migration/
I replaced api key and secret with the new Client id and Client secret and updated signature generation with the new keys.

I tested the new credentials with the sample app zoom-sdk-web-2.10.1, which worked perfectly
I updated the html of my web app to the new version 2.10.1 but i keep getting a signature error.

Browser Console Error
method: ā€˜joinā€™, status: false, result: ā€˜Invalid signature.ā€™, errorMessage: ā€˜Signature is invalid.ā€™, errorCode: 3712

Which Web Meeting SDK version?
version 2.10.1

Meeting SDK Code Snippets

//This is the JS code for the Join function

function Join() {
    var url = "https://dev.learningleaders.com/modules/zoom/credentials.php?";
    var sdkKey = "4r5dbBgSRneDqTkY65K5Q";
    var meeting_number = URL_GetParam("meeting_number");
    var password = URL_GetParam("password");
    var role = URL_GetParam("role");
    var user_name = URL_GetParam("user_name");

    console.log(user_name);

    Request_Load(
      url +
        "sdkKey=" +
        sdkKey +
        "&meeting_number=" +
        meeting_number +
        "&role=" +
        role,
      function (signature) {
        ZoomMtg.join({
          signature: signature,
          meetingNumber: meeting_number,
          userName: user_name,
          sdkKey: sdkKey,
          passWord: password,
          success: (success) => {
            console.log(success);
          },

          error: (error) => {
            console.log(error);
          },
        });
      }
    );
  }

// This is the credential.php code to generate the signature

<?PHP
 $sdkKey        = $_REQUEST["sdkKey"];
 $meeting_number = $_REQUEST["meeting_number"];
 $role           = $_REQUEST["role"]; 
 $sdk_secret     = "redacted";

 //Set the timezone to UTC
 date_default_timezone_set("UTC");
 
 $time = time() + 60 * 60 * 2;; //time in seconds
 $data = base64_encode($sdkKey . $meeting_number . $time . $role);
 $hash = hash_hmac('sha256', $data, $sdk_secret, true);
 $_sig = $sdkKey . "." . $meeting_number . "." . $time . "." . $role . "." . base64_encode($hash);

 $signature =  rtrim(strtr(base64_encode($_sig), '+/', '-_'), '=');

 echo $signature;
 
?>

Troubleshooting Routes

Please note I already tried changing different versions of zoom integration.
I was using 2.4 with JTW and tried 2.7 , 2.8 and finally 2.10.1 with SDK.
I tried reading the forum for inspiration but i didnā€™t find a real solution that applies to me.
The error would suggest I am still using a JWT key but I am not.
I also tried a different code to generate siganture, as suggested on the Forum.
Everything i tried DID generate a signature but always an invalid one.

Credential are working on the sample app and the php code works as it does generate a signature.
time is in seconds and not in milliseconds as suggested on other similar topics.
I am open to suggestions.

Device (please complete the following information):

  • Device: Personal PC
  • OS: Windows
  • Browser: Chrome latest version

@ghidonf ,

Iā€™m thinking out loud for now as a preliminary assessment.
It is possible that the POST / GET request did not complete before join is being called?

There is a possibility that the request to https://dev.learningleaders.com/modules/zoom/credentials.php to generate your JWT token has not completed, hence the signature is still ā€œā€ or null

your code for the JWT Token, not for SDK JWT Token (change time from ms to sec is not enough)

here is link to a php solution

and here the reference implemention in js

here you can check the signature token

Thanks everyone for your support.

@chunsiong.zoom Not the case but good thinking. That was a JWT app already working, the request was complete.

@j.schoenemeyer I tried that code too, the code I implemented as an example is just one of the many, actually the older, so yes, as you say, not good as it was for JWT Token and not SDK.
I also found at least two other similar examples to work with PHP and generate an SDK JWT Token but all of them were using third party software for encryption which I canā€™t use here.

Bottom line, I managed to crack it yesterday evening and the issue was a mixing of the right code and the right version together. Apparently, at some point, it was developed a version which requires specific header and payload to get a signature with the secret key.
My mistake was to try the new code with an older version first and then update the version and try again with older and incomplete code.

I am posting the final working result to request a valid SDK JWT Signature withouth using third party software.

<?PHP
 $sdk_key        = $_REQUEST["sdkKey"];  // This could be sdkKey or Client Id in the newest v. 2.10.1
 $sdk_secret     = " Your Secret key "; // This could be sdkKey secret or Client Secret in the newest v. 2.10.1

 $meeting_number = $_REQUEST["meeting_number"];
 $role           = $_REQUEST["role"]; 

 function base64url_encode($str) {
    return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}

 
$headers = array(
    'alg' => 'HS256', //alg is required
    'typ' => 'JWT'
    );

date_default_timezone_set("UTC");
$time = time() - 30;
$exp = $time + 3600 * 2;

$payload = array(
    'sdkKey' => $sdk_key,
    'mn' => $meeting_number,       // meeting number that you send via post request
    'role' => $role, // 0 guest or 1 host via post request 
    'iat' => $time,
    'exp' => $exp,
    'appKey' => $sdk_key,
    'tokenExp' => $exp,
);

$key = $sdk_secret;


function generate_jwt($headers, $payload, $key) {
	$headers_encoded = base64url_encode(json_encode($headers));
	
	$payload_encoded = base64url_encode(json_encode($payload));
	
	$signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $key, true);
	$signature_encoded = base64url_encode($signature);
	
	$jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
	
	return $jwt;
}

$jws = $jwt = generate_jwt($headers, $payload, $key);

echo $jwt;
 
?>

JS code previously posted did not change, just the PHP code to request the signature was changed.

Thanks everybody, I hope that helps someone else too.

1 Like

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