forked from nelmio/NelmioSecurityBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Signer.php
81 lines (64 loc) · 2.12 KB
/
Signer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
/*
* This file is part of the Nelmio SecurityBundle.
*
* (c) Nelmio <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Nelmio\SecurityBundle;
class Signer
{
private $secret;
private $algo;
public function __construct($secret, $algo)
{
$this->secret = $secret;
$this->algo = $algo;
if (!in_array($this->algo, hash_algos(), true)) {
throw new \InvalidArgumentException(sprintf("The supplied hashing algorithm '%s' is not supported by this system.",
$this->algo));
}
}
public function getSignedValue($value, $signature = null)
{
if (null === $signature) {
$signature = $this->generateSignature($value);
}
return $value.'.'.$signature;
}
public function verifySignedValue($signedValue)
{
list($value, $signature) = $this->splitSignatureFromSignedValue($signedValue);
$signature2 = $this->generateSignature($value);
if (strlen($signature) !== strlen($signature2)) {
return false;
}
$result = 0;
for ($i = 0, $j = strlen($signature); $i < $j; ++$i) {
$result |= ord($signature[$i]) ^ ord($signature2[$i]);
}
return 0 === $result;
}
public function getVerifiedRawValue($signedValue)
{
if (!$this->verifySignedValue($signedValue)) {
throw new \InvalidArgumentException(sprintf("The signature for '%s' was invalid.", $signedValue));
}
$valueSignatureTuple = $this->splitSignatureFromSignedValue($signedValue);
return $valueSignatureTuple[0];
}
private function generateSignature($value)
{
return hash_hmac($this->algo, $value, $this->secret);
}
private function splitSignatureFromSignedValue($signedValue)
{
$pos = strrpos($signedValue, '.');
if (false === $pos) {
return array($signedValue, null);
}
return array(substr($signedValue, 0, $pos), substr($signedValue, $pos + 1));
}
}