feat(cloud): HMAC sign/verify matching P1-A edge contract
This commit is contained in:
parent
50cb2cfe82
commit
8e62304471
2 changed files with 42 additions and 0 deletions
17
cloud/src/Security/Hmac.php
Normal file
17
cloud/src/Security/Hmac.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace App\Security;
|
||||
|
||||
final class Hmac
|
||||
{
|
||||
public static function sign(string $secret, string $nonce, string $ts, string $body): string
|
||||
{
|
||||
return hash_hmac('sha256', $nonce . $ts . $body, $secret);
|
||||
}
|
||||
|
||||
public static function verify(string $secret, string $nonce, string $ts, string $body, string $sig): bool
|
||||
{
|
||||
$expected = self::sign($secret, $nonce, $ts, $body);
|
||||
return hash_equals($expected, $sig);
|
||||
}
|
||||
}
|
||||
25
cloud/tests/HmacTest.php
Normal file
25
cloud/tests/HmacTest.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace App\Tests;
|
||||
use App\Security\Hmac;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class HmacTest extends TestCase
|
||||
{
|
||||
public function testSignMatchesPythonEdgeContract(): void
|
||||
{
|
||||
// P1-A edge/alert.py::sign = HMAC-SHA256(nonce+ts+body, secret) hex
|
||||
$sig = Hmac::sign('secret', 'n1', '1000.0', '{"a":1}');
|
||||
$expected = hash_hmac('sha256', 'n1' . '1000.0' . '{"a":1}', 'secret');
|
||||
$this->assertSame($expected, $sig);
|
||||
$this->assertSame(64, strlen($sig));
|
||||
}
|
||||
|
||||
public function testVerifyTrueOnMatchFalseOnTamper(): void
|
||||
{
|
||||
$sig = Hmac::sign('secret', 'n1', '1000.0', 'body');
|
||||
$this->assertTrue(Hmac::verify('secret', 'n1', '1000.0', 'body', $sig));
|
||||
$this->assertFalse(Hmac::verify('secret', 'n1', '1000.0', 'body-TAMPERED', $sig));
|
||||
$this->assertFalse(Hmac::verify('wrong', 'n1', '1000.0', 'body', $sig));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue