Generate Request Signature
HMAC-SHA256 over METHOD|PATH|TIMESTAMP|BODY. Use the active signing key as the secret.
TypeScript
import crypto from 'crypto';
export function generateApiSignature({
method,
path,
body,
apiSecret,
}: {
method: string;
path: string;
body: unknown;
apiSecret: string;
}): { timestamp: string; signature: string } {
const timestamp = Date.now().toString();
const canonicalBody = ['GET', 'DELETE', 'HEAD', 'OPTIONS'].includes(
method.toUpperCase(),
)
? ''
: body
? JSON.stringify(body)
: '';
const canonicalString = [method.toUpperCase(), path, timestamp, canonicalBody].join('|');
const signature = crypto
.createHmac('sha256', apiSecret)
.update(canonicalString)
.digest('hex');
return { timestamp, signature };
}
Python
import hmac
import hashlib
import json
import time
def generate_api_signature(method: str, path: str, body, api_secret: str):
timestamp = str(int(time.time() * 1000))
if method.upper() in ('GET', 'DELETE', 'HEAD', 'OPTIONS'):
canonical_body = ''
else:
canonical_body = json.dumps(body, separators=(',', ':')) if body else ''
canonical = '|'.join([method.upper(), path, timestamp, canonical_body])
signature = hmac.new(
api_secret.encode('utf-8'),
canonical.encode('utf-8'),
hashlib.sha256,
).hexdigest()
return timestamp, signature
Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Set;
public class BridgSignature {
private static final Set<String> EMPTY_BODY = Set.of("GET", "DELETE", "HEAD", "OPTIONS");
public static String[] generate(String method, String path, String body, String apiSecret) throws Exception {
String timestamp = String.valueOf(System.currentTimeMillis());
String canonicalBody = EMPTY_BODY.contains(method.toUpperCase()) ? "" : (body == null ? "" : body);
String canonical = String.join("|", method.toUpperCase(), path, timestamp, canonicalBody);
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(apiSecret.getBytes("UTF-8"), "HmacSHA256"));
byte[] sig = mac.doFinal(canonical.getBytes("UTF-8"));
StringBuilder hex = new StringBuilder();
for (byte b : sig) hex.append(String.format("%02x", b));
return new String[]{ timestamp, hex.toString() };
}
}
PHP
<?php
function generate_api_signature(string $method, string $path, $body, string $apiSecret): array {
$timestamp = (string) round(microtime(true) * 1000);
if (in_array(strtoupper($method), ['GET', 'DELETE', 'HEAD', 'OPTIONS'], true)) {
$canonicalBody = '';
} else {
$canonicalBody = $body ? json_encode($body, JSON_UNESCAPED_SLASHES) : '';
}
$canonical = implode('|', [strtoupper($method), $path, $timestamp, $canonicalBody]);
$signature = hash_hmac('sha256', $canonical, $apiSecret);
return ['timestamp' => $timestamp, 'signature' => $signature];
}