/**
* Generate signature for ZoomMtg WebSDK. {@link https://github.com/danharper/hmac-examples|hmac-examples}
* @param string $api_key You REST API Key
* @param string $api_secret You REST API Secret
* @param int $meeting_number The meeting number you are creating the signature for
* @param int $role Role that this signature is for; 0 for participant, 1 for host
* @return {string} Returns the signature string
* @method generate_signature
* @example
//======================================================================================================
//PHP example code
function generate_signature ( $api_key, $api_sercet, $meeting_number, $role){
$time = time() * 1000 - 30000; //time in milliseconds (or close enough)
$data = base64_encode($api_key . $meeting_number . $time . $role);
$hash = hash_hmac('sha256', $data, $api_sercet, true);
$_sig = $api_key . "." . $meeting_number . "." . $time . "." . $role . "." . base64_encode($hash);
//return signature, url safe base64 encoded
return rtrim(strtr(base64_encode($_sig), '+/', '-_'), '=');
}
//======================================================================================================
//Java example code
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.security.InvalidKeyException;
import javax.xml.bind.DatatypeConverter;
public class test {
public static String generateSignature(String apiKey, String apiSecret, String meetingNumber, Integer role) {
try {
Mac hasher = Mac.getInstance("HmacSHA256");
String ts = Long.toString(System.currentTimeMillis() - 30000);
String msg = String.format("%s%s%s%d", apiKey, meetingNumber, ts, role);
hasher.init(new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256"));
String message = Base64.getEncoder().encodeToString(msg.getBytes());
byte[] hash = hasher.doFinal(message.getBytes());
String hashBase64Str = DatatypeConverter.printBase64Binary(hash);
String tmpString = String.format("%s.%s.%s.%d.%s", apiKey, meetingNumber, ts, role, hashBase64Str);
String encodedString = Base64.getEncoder().encodeToString(tmpString.getBytes());
return encodedString.replaceAll("\\=+$", "");
}
catch (NoSuchAlgorithmException e) {}
catch (InvalidKeyException e) {}
return "";
}
public static void main(String[] args) {
String signature = test.generateSignature("apiKey", "apiSecret", "meetingNumber", 0);
System.out.println(signature);
}
}
//======================================================================================================
//Python2 example code
import hashlib
import hmac
import base64
import time
def generateSignature(data):
ts = (int(round(time.time() * 1000)) - 30000); #ts; // 1544683367752
print (ts)
msg = data['apiKey'] + str(data['meetingNumber']) + str(ts) + str(data['role']);
message = base64.b64encode(bytes(msg).encode('utf-8'));
secret = bytes(data['apiSecret']).encode('utf-8')
hash = hmac.new(secret, message, hashlib.sha256);
hash = base64.b64encode(hash.digest());
hash = hash.decode("utf-8");
tmpString = "%s.%s.%s.%s.%s" % (data['apiKey'], str(data['meetingNumber']), str(ts), str(data['role']), hash);
signature = base64.b64encode(bytes(tmpString).encode("utf-8"));
signature = signature.decode("utf-8");
return signature.rstrip("=");
if __name__ == '__main__':
data = {'apiKey': "" ,
'apiSecret': "",
'meetingNumber': 8998,
'role': 0}
print (generateSignature(data))
//======================================================================================================
//Python3 example code
import hashlib
import hmac
import base64
import datetime
def generateSignature(data):
ts = int(round(datetime.datetime.utcnow().timestamp() * 1000)) - 30000;
msg = data['apiKey'] + str(data['meetingNumber']) + str(ts) + str(data['role']);
message = base64.b64encode(bytes(msg, 'utf-8'));
# message = message.decode("utf-8");
secret = bytes(data['apiSecret'], 'utf-8')
hash = hmac.new(secret, message, hashlib.sha256);
hash = base64.b64encode(hash.digest());
hash = hash.decode("utf-8");
tmpString = "%s.%s.%s.%s.%s" % (data['apiKey'], str(data['meetingNumber']), str(ts), str(data['role']), hash);
signature = base64.b64encode(bytes(tmpString, "utf-8"));
signature = signature.decode("utf-8");
return signature.rstrip("=");
if __name__ == '__main__':
data = {'apiKey': "" ,
'apiSecret': "",
'meetingNumber': 888,
'role': 0}
print (generateSignature(data))
//======================================================================================================
//Nodejs
// npm install --save-dev js-base64 crypto-js
const base64JS = require('js-base64');
const hmacSha256 = require('crypto-js/hmac-sha256');
const encBase64 = require('crypto-js/enc-base64');
function generateSignature(data) {
let signature = '';
// Prevent time sync issue between client signature generation and zoom
const ts = new Date().getTime() - 30000;
const msg = base64JS.Base64.encode(data.apiKey + data.meetingNumber + ts + data.role);
const hash = hmacSha256(msg, data.apiSecret);
signature = base64JS.Base64.encodeURI(`${data.apiKey}.${data.meetingNumber}.${ts}.${data.role}.${encBase64.stringify(hash)}`);
return signature;
}
const data = {apiKey: "" ,
apiSecret: "",
meetingNumber: 888,
role: 0}
console.log(generateSignature(data));
//======================================================================================================
// WebSDK us this generateSignature
// npm install --save-dev js-base64 crypto-js
import * as base64JS from 'js-base64';
import * as hmacSha256 from 'crypto-js/hmac-sha256';
import * as encBase64 from 'crypto-js/enc-base64';
function generateSignature(data) {
let signature = '';
const ts = new Date().getTime() - 30000;
try {
const msg = base64JS.Base64.encode(data.apiKey + data.meetingNumber + ts + data.role);
const hash = hmacSha256.default(msg, data.apiSecret);
signature = base64JS.Base64.encodeURI(`${data.apiKey}.${data.meetingNumber}.${ts}.${data.role}.${encBase64.stringify(hash)}`);
} catch (e) {
console.log('error');
}
return signature;
}
*
//======================================================================================================
// C#
// 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
// 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.Security.Cryptography;
using System.Text;
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 ?? "";
// Console.WriteLine ("message: " + message + " secret: " + apiSecret);
var encoding = new System.Text.ASCIIEncoding ();
byte[] keyByte = encoding.GetBytes (apiSecret);
byte[] messageBytes = encoding.GetBytes (message);
// Console.WriteLine (System.Convert.ToBase64String (messageBytes));
using (var hmacsha256 = new HMACSHA256 (keyByte)) {
byte[] key1 = Encoding.ASCII.GetBytes (apiSecret);
byte[] hashmessage = hmacsha256.ComputeHash (messageBytes);
string msgHash = System.Convert.ToBase64String (hashmessage);
// Console.WriteLine ("msgHash: " + msgHash);
string token = String.Format ("{0}.{1}.{2}.{3}.{4}", apiKey, meetingNumber, ts, role, msgHash);
// Console.WriteLine("token", token, " ", Base64Encode(token));
var tokenBytes = System.Text.Encoding.UTF8.GetBytes (token);
return System.Convert.ToBase64String (tokenBytes).TrimEnd(padding);
}
}
}
}
*/