Skip to content

Commit 150320d

Browse files
authored
Default SDK signatures to sha384 (#63)
* Default PHP SDK request signatures to sha384 * Normalize invalid signature algorithm errors
1 parent fe38e2d commit 150320d

6 files changed

Lines changed: 61 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
diff: https://github.com/transloadit/php-sdk/compare/3.3.0...main
66

7+
- Default Assembly signatures to `sha384` and include the algorithm prefix (`sha384:...`)
8+
- Add request/client-level `signatureAlgorithm` configuration for legacy `sha1` compatibility
9+
- Extend tests to cover default `sha384` signing, legacy override, and Node CLI parity
10+
711
## [3.3.0](https://github.com/transloadit/php-sdk/tree/3.3.0)
812

913
- Replace the custom Node parity helper with the official `transloadit` CLI for Smart CDN signatures

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,12 @@ The auth key of your Transloadit account.
358358
359359
The auth secret of your Transloadit account.
360360
361+
#### $Transloadit->signatureAlgorithm = 'sha384';
362+
363+
Controls which HMAC algorithm is used for Assembly request signing.
364+
The default is `'sha384'` (recommended). If you need compatibility with a legacy key,
365+
you can set this to `'sha1'`.
366+
361367
#### $Transloadit->request($options = [], $execute = true);
362368
363369
Creates a new `TransloaditRequest` using the `$Transloadit->key` and
@@ -444,6 +450,12 @@ The auth key of your Transloadit account.
444450
445451
The auth secret of your Transloadit account.
446452
453+
#### $TransloaditRequest->signatureAlgorithm = 'sha384';
454+
455+
Controls which HMAC algorithm is used when preparing the Assembly request signature.
456+
The generated `signature` field uses the `<algorithm>:<digest>` format, for example:
457+
`sha384:...`.
458+
447459
#### $TransloaditRequest->method = 'GET';
448460
449461
Inherited from `CurlRequest`. Can be used to set the type of request to be

lib/transloadit/Transloadit.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
class Transloadit {
66
public $key = null;
77
public $secret = null;
8+
public $signatureAlgorithm = 'sha384';
89
public $endpoint = 'https://api2.transloadit.com';
910

1011
public function __construct($attributes = []) {
@@ -17,6 +18,7 @@ public function request($options = [], $execute = true) {
1718
$options = $options + [
1819
'key' => $this->key,
1920
'secret' => $this->secret,
21+
'signatureAlgorithm' => $this->signatureAlgorithm,
2022
'endpoint' => $this->endpoint,
2123
'waitForCompletion' => false,
2224
];

lib/transloadit/TransloaditRequest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class TransloaditRequest extends CurlRequest {
1414

1515
public $params = [];
1616
public $expires = '+2 hours';
17+
public $signatureAlgorithm = 'sha384';
1718

1819
public $headers = [
1920
'Expect:',
@@ -42,12 +43,27 @@ public function getParamsString() {
4243
return json_encode($params);
4344
}
4445

45-
public function signString($string) {
46+
public function signString($string, $algorithm = null) {
4647
if (empty($this->secret)) {
4748
return null;
4849
}
4950

50-
return hash_hmac('sha1', $string, $this->secret);
51+
$effectiveAlgorithm = strtolower((string) ($algorithm ?? $this->signatureAlgorithm ?? 'sha384'));
52+
if ($effectiveAlgorithm === '') {
53+
$effectiveAlgorithm = 'sha384';
54+
}
55+
56+
try {
57+
$signature = hash_hmac($effectiveAlgorithm, $string, $this->secret);
58+
} catch (\ValueError $e) {
59+
throw new \InvalidArgumentException('Unsupported signature algorithm: ' . $effectiveAlgorithm, 0, $e);
60+
}
61+
62+
if ($signature === false) {
63+
throw new \InvalidArgumentException('Unsupported signature algorithm: ' . $effectiveAlgorithm);
64+
}
65+
66+
return $effectiveAlgorithm . ':' . $signature;
5167
}
5268

5369
public function prepare() {

test/simple/TransloaditRequestTest.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public function testAttributes() {
2323
$this->assertEquals($this->request->secret, null);
2424
$this->assertEquals($this->request->params, []);
2525
$this->assertEquals($this->request->expires, '+2 hours');
26+
$this->assertEquals($this->request->signatureAlgorithm, 'sha384');
2627
$this->assertEquals('Expect:', $this->request->headers[0]);
2728
$this->assertContains('Transloadit-Client: php-sdk:%s', $this->request->headers);
2829
}
@@ -99,13 +100,28 @@ public function testSignString() {
99100
// No secret, no signature
100101
$this->assertEquals(null, $this->request->signString('foo'));
101102

102-
// Verify the test vector given in the documentation, see: http://transloadit.com/docs/authentication
103+
// Verify the test vector (default sha384 + algorithm prefix)
103104
$this->request->secret = 'd805593620e689465d7da6b8caf2ac7384fdb7e9';
104-
$expectedSignature = 'fec703ccbe36b942c90d17f64b71268ed4f5f512';
105+
$expectedSignature = 'sha384:69b74f954488cbb571cace210ae9039d18d84ec57edc784d19fd364f4295c99c93c14f0fed7f245b480d5856f12effc2';
105106

106107
$params = '{"auth":{"expires":"2010\/10\/19 09:01:20+00:00","key":"2b0c45611f6440dfb64611e872ec3211"},"steps":{"encode":{"robot":"\/video\/encode"}}}';
107108
$signature = $this->request->signString($params);
108109
$this->assertEquals($expectedSignature, $signature);
110+
111+
// Explicit algorithm override for legacy keys
112+
$legacySignature = $this->request->signString($params, 'sha1');
113+
$this->assertEquals('sha1:fec703ccbe36b942c90d17f64b71268ed4f5f512', $legacySignature);
114+
115+
// Request-level override should affect default signing behavior
116+
$this->request->signatureAlgorithm = 'sha1';
117+
$this->assertEquals('sha1:fec703ccbe36b942c90d17f64b71268ed4f5f512', $this->request->signString($params));
118+
}
119+
120+
public function testSignStringWithInvalidAlgorithmThrowsInvalidArgumentException() {
121+
$this->request->secret = 'secret';
122+
$this->expectException(\InvalidArgumentException::class);
123+
$this->expectExceptionMessage('Unsupported signature algorithm: definitely-not-a-real-algorithm');
124+
$this->request->signString('payload', 'definitely-not-a-real-algorithm');
109125
}
110126

111127
public function testGetParamsString() {
@@ -146,7 +162,7 @@ public function testSignatureParityWithNodeCli(): void {
146162
'width' => 320,
147163
],
148164
],
149-
], 'cli-key', 'cli-secret', 'sha1');
165+
], 'cli-key', 'cli-secret', 'sha384');
150166

151167
$this->assertNotNull($cliResult);
152168
$this->assertArrayHasKey('signature', $cliResult);
@@ -166,8 +182,9 @@ public function testSignatureParityWithNodeCli(): void {
166182
$cliParams['steps']['resize']['width']
167183
);
168184

169-
$expectedSignature = hash_hmac('sha1', $cliResult['params'], 'cli-secret');
170-
$this->assertEquals('sha1:' . $expectedSignature, $cliResult['signature']);
185+
$expectedSignature = hash_hmac('sha384', $cliResult['params'], 'cli-secret');
186+
$this->assertEquals('sha384:' . $expectedSignature, $cliResult['signature']);
187+
$this->assertEquals($cliResult['signature'], $request->signString($cliResult['params']));
171188
}
172189

173190
public function testExecute() {

test/simple/TransloaditTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public function testConstructor() {
2121
public function testAttributes() {
2222
$this->assertEquals($this->transloadit->key, null);
2323
$this->assertEquals($this->transloadit->secret, null);
24+
$this->assertEquals($this->transloadit->signatureAlgorithm, 'sha384');
2425
}
2526

2627
public function testCreateAssembly() {
@@ -78,10 +79,12 @@ public function testCancelAssembly() {
7879
public function testRequest() {
7980
$this->transloadit->key = 'my-key';
8081
$this->transloadit->secret = 'my-secret';
82+
$this->transloadit->signatureAlgorithm = 'sha1';
8183
$request = $this->transloadit->request(['url' => 'foobar'], false);
8284

8385
$this->assertEquals($this->transloadit->key, $request->key);
8486
$this->assertEquals($this->transloadit->secret, $request->secret);
87+
$this->assertEquals($this->transloadit->signatureAlgorithm, $request->signatureAlgorithm);
8588
$this->assertEquals('foobar', $request->url);
8689

8790
// Unfortunately we can't test the $execute parameter because PHP

0 commit comments

Comments
 (0)