🚀 مُصادَق: تحديث برمجي جديد 2026-05-03 15:11

This commit is contained in:
Hamza-Ayed
2026-05-03 15:11:34 +03:00
parent 3aeb3220f1
commit 7cd2d91576
23 changed files with 1418 additions and 879 deletions

View File

@@ -11,35 +11,29 @@ final class HmacService
/**
* Verify HMAC signature for external API requests (Flutter)
*/
public function verify(
string $secret,
string $method,
string $path,
string $timestamp,
string $nonce,
string $body,
string $providedSignature
): bool {
// 1. Check timestamp (within 5 minutes)
if (abs(time() - (int)$timestamp) > 300) {
return false;
public function verify(string $secret, string $method, string $path,
string $timestamp, string $nonce, string $body, string $signature): bool
{
// 1. Timestamp window (±5 minutes)
if (abs(time() - (int)$timestamp) > 300) return false;
// 2. Nonce replay protection
try {
$redis = \App\Core\Redis::getInstance();
$nonceKey = 'hmac_nonce:' . $nonce;
if ($redis->exists($nonceKey)) return false; // Replay attack
$redis->setex($nonceKey, 600, '1'); // TTL 10 minutes
} catch (\Throwable $e) {
// Redis unavailable — log but don't fail (degrade gracefully)
error_log('[HMAC] Redis unavailable for nonce check: ' . $e->getMessage());
}
// 2. Replay protection using Nonce in Redis
// Note: Redis::getInstance() would be used here
// If nonce exists, reject
// 3. Calculate Signature
// 3. Build & compare signature
$bodyHash = hash('sha256', $body);
$stringToSign = strtoupper($method) . "\n" .
$path . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$bodyHash;
$stringToSign = strtoupper($method) . "\n" . $path . "\n" . $timestamp . "\n" . $nonce . "\n" . $bodyHash;
$calculated = hash_hmac('sha256', $stringToSign, $secret);
$calculatedSignature = hash_hmac('sha256', $stringToSign, $secret);
return hash_equals($calculatedSignature, $providedSignature);
return hash_equals($calculated, $signature);
}
public function sign(string $secret, string $method, string $path, string $timestamp, string $nonce, string $body): string