Secure API Calls: Signature, Encryption, and Unified Response Formats
This guide explains how to implement API request signatures, encrypt sensitive data using SM4, and standardize response structures, providing step‑by‑step instructions, code examples in PHP, and security best practices to protect API integrity and confidentiality.
Interface Signature
API signatures ensure request integrity and authentication by signing request parameters.
Implementation Steps
Parameter Collection : Gather all parameters to be sent, such as user ID, operation type, and request data.
Sorting : Sort parameters alphabetically to guarantee a consistent signature.
String Concatenation : Concatenate the HTTP method, request path, sorted parameters, a timestamp, and a secret key.
stringToSign = method + path + params + timestamp + secretKey method: HTTP method (GET, POST, etc.) path: API endpoint path params: Sorted parameter string timestamp: Request timestamp secretKey: Shared secret known only to client and server
Hash Encryption : Apply a hash function (e.g., MD5, SHA‑1, SHA‑256) to the concatenated string. sign = hash(stringToSign) Send Request : Include the sign value in request headers or parameters.
Server Verification : The server recomputes the signature using the same method and compares it with the client‑provided value; a match indicates a legitimate request.
Security Considerations
Keep the secretKey confidential.
Use HTTPS to protect the transmission channel.
Include a timestamp to prevent replay attacks and validate its freshness.
Error Handling : If verification fails, return an error response and log the event. Signatures do not encrypt data; additional encryption is needed for sensitive payloads.
Example: Generating a Key Pair
$originalUuid = Uuid::uuid4()->toString();
$app_key = str_replace('-', '', $originalUuid); // unique identifier
$timestamp = time();
$app_secret = sha1($app_key . '|' . $timestamp); // sha1(app_key + update_time)
$createData = [
'app_name' => 'Acme Platform',
'app_key' => $app_key,
'app_secret' => password_hash($app_secret, PASSWORD_DEFAULT), // store encrypted
'create_time' => $timestamp,
'update_time' => $timestamp,
];
if (AppModel::create($createData)) {
return response_json(200, 'ok');
}Example: Verifying a Signature
// [1] Retrieve signature from request header
$signature = $this->request->header()['x-resty-signature'] ?? '';
// [2] Parse signature to obtain hash algorithm and hash value
list($hashType, $hashValue) = explode('=', $signature, 2);
// [3] Get request body (JSON string)
$jsonContent = $this->request->getContent();
if (empty($jsonContent)) {
return response_json(400, 'Request body cannot be empty');
}
$arrayContent = json_decode($jsonContent, true);
if (!isset($arrayContent['app_key']) || !isset($arrayContent['timestamp'])) {
return response_json(400, 'app_key and timestamp are required');
}
if (($arrayContent['timestamp'] + 20) < time()) {
return response_json(403, 'timestamp expired');
}
$appInfo = AppModel::where('app_key', $arrayContent['app_key'])->findOrEmpty();
if ($appInfo->isEmpty()) {
return response_json(400, 'Invalid app_key');
}
// [4] Generate appSecret
$appSecret = sha1($appInfo->app_key . '|' . $appInfo->update_time);
// [5] Compute HMAC using the provided algorithm and secret
$checkHash = hash_hmac($hashType, json_encode($arrayContent), $appSecret);
// [6] Compare hashes
if ($checkHash != $hashValue) {
return response_json(403, 'Invalid signature', $this->request->header());
}
return response_json(200, 'ok', $arrayContent);Data Encryption
When APIs handle sensitive information such as passwords, bank cards, or identity numbers, transmitting them in plain text poses severe security risks.
Security Recommendations
Use HTTPS : Always transmit data over HTTPS to leverage SSL/TLS encryption.
Client‑Side Encryption : Encrypt highly sensitive fields (e.g., passwords) on the client before sending.
Hash Passwords : Store passwords using strong hash functions like bcrypt, scrypt, or Argon2 instead of plain text.
Example: SM4 Symmetric Encryption
SM4 is a 128‑bit block cipher similar to AES. The same key encrypts and decrypts data.
Encryption
$key = '35d251411ea04318565f0dbda6ffb6a8';
$content = [
'name' => 'Tinywan',
'School' => 'ZheJiang University',
'age' => 24,
'github' => [
'url' => 'https://github.com/Tinywan',
'start' => 2000,
],
];
$content = json_encode($content, JSON_UNESCAPED_UNICODE);
$sm4 = new SM4($key);
$encryptContent = $sm4->encrypt($content);
var_dump($encryptContent);Decryption
$key = '35d251411ea04318565f0dbda6ffb6a8';
$encryptContent = 'b4358f5860343dbf2089ba75ee55deca8d922a069413f39cb3f8b64c01048c780ba5f03290642505d65d79c59684d76cf42443047f547c9f29dc2a49f872a2719ce00539058ab1fb5830e8e0c10144b574a87118390baa765b3429ba7afe5d28';
$sm4 = new SM4($key);
$decryptedJsonContent = $sm4->decrypt($encryptContent);
print_r($decryptedJsonContent);The decrypted JSON can be converted to an array with json_decode($decryptedJsonContent, true) .
Unified Response Format
Consistent API responses improve developer efficiency, reduce errors, and simplify integration.
Format Recommendations
Version Number : Include an API version in every response for backward compatibility.
Standard Status Codes : Use HTTP status codes (200, 400, 500, etc.) to indicate result.
Data Wrapper : Place the actual payload inside a uniform data field.
Pagination Info : When returning lists, provide total, perPage, currentPage, and totalPages fields.
Examples
Success
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"code": 0,
"msg": "success",
"data": {
"token_type": "Bearer",
"expires_in": 7200,
"access_token": "XXXXXXXXXXX"
}
}Error
HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8
{
"code": 0,
"msg": "应用信息不存在",
"data": {}
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
