Rev 868 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
868 | daniel-mar | 1 | <?php |
2 | /** |
||
3 | * SBrook\JWS\JwsMac |
||
4 | */ |
||
5 | |||
6 | namespace SBrook\JWS; |
||
7 | |||
8 | use SBrook\JWS\Exception\JwsException; |
||
9 | |||
10 | /** |
||
11 | * Class JwsMac |
||
12 | * @package SBrook\JWS |
||
13 | * @throws JwsException: |
||
14 | * 30. Secret key should be a non empty string |
||
15 | */ |
||
16 | class JwsMac extends Jws implements Symmetric { |
||
17 | /** |
||
18 | * JWS signature secret key. |
||
19 | * @var string |
||
20 | */ |
||
21 | protected $secretKey = ""; |
||
22 | |||
23 | /** |
||
24 | * Default signature algorithm. |
||
25 | * @var string |
||
26 | */ |
||
27 | protected $defaultAlgo = "HS256"; |
||
28 | |||
29 | /** |
||
30 | * Signature algorithms map JWS => hash_hmac(). |
||
31 | * |
||
32 | * JWS signature algorithms (RFC 7518, Section 3.2) - "alg": |
||
33 | * HS256: HMAC using SHA-256 - Min recommended key length: 32 bytes |
||
34 | * HS384: HMAC using SHA-384 - Min recommended key length: 48 bytes |
||
35 | * HS512: HMAC using SHA-512 - Min recommended key length: 64 bytes |
||
36 | * |
||
37 | * @var array |
||
38 | */ |
||
39 | protected $algos = [ |
||
40 | "HS256" => "SHA256", |
||
41 | "HS384" => "SHA384", |
||
42 | "HS512" => "SHA512" |
||
43 | ]; |
||
44 | |||
45 | /** |
||
46 | * JwsMac constructor. |
||
47 | * @param string $key - JWS signature secret key. |
||
48 | * @throws JwsException |
||
49 | */ |
||
50 | public function __construct($key) { |
||
51 | if (is_string($key) && strlen($key) > 0) { |
||
52 | $this->secretKey = $key; |
||
53 | } else { |
||
54 | throw new JwsException("Secret key should be a non empty string", 30); |
||
55 | } |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * JwsMac destructor. |
||
60 | */ |
||
61 | public function __destruct() { |
||
62 | unset( |
||
63 | $this->secretKey, |
||
64 | $this->defaultAlgo, |
||
65 | $this->algos |
||
66 | ); |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Set JWS signature secret key - overwrites previously set key. |
||
71 | * @param string $key - JWS signature secret key. |
||
72 | * @param $pass - (Optional) Not in use. |
||
73 | * @throws JwsException |
||
74 | */ |
||
75 | public function setSecretKey($key, $pass = "") { |
||
76 | if (is_string($key) && strlen($key) > 0) { |
||
77 | $this->secretKey = $key; |
||
78 | } else { |
||
79 | throw new JwsException("Secret key should be a non empty string", 30); |
||
80 | } |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Create JWS from payload and optional header and sign it. |
||
85 | * @param string $payload - Payload. |
||
86 | * @param array $header - (Optional) Header data. |
||
87 | * @return string - JWS. |
||
88 | * @throws JwsException |
||
89 | */ |
||
90 | public function sign($payload, $header = []) { |
||
91 | $d = $this->prepareSign($this->defaultAlgo, $payload, $header); |
||
92 | return $d["h"] . "." . $d["p"] . "." . base64_encode(hash_hmac($this->algos[$d["alg"]], $d["h"] . "." . $d["p"], $this->secretKey, true)); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Verify JWS signature. |
||
97 | * @param string $jws - JWS. |
||
98 | * @return bool - TRUE on valid signature, FALSE on invalid. |
||
99 | * @throws JwsException |
||
100 | */ |
||
101 | public function verify($jws) { |
||
102 | $d = $this->prepareVerify($jws); |
||
1470 | daniel-mar | 103 | return hash_equals(hash_hmac($this->algos[$d["alg"]], $d["h"] . "." . $d["p"], $this->secretKey, true), $d["sig"]); |
868 | daniel-mar | 104 | } |
105 | |||
106 | /** |
||
107 | * Check validity of signature algorithm. |
||
108 | * @param string $algorithm - Algorithm name. |
||
109 | * @return bool - TRUE on valid algorithm, FALSE on invalid. |
||
110 | */ |
||
111 | protected function isValidAlgorithm(string $algorithm): bool { |
||
112 | return array_key_exists(strtoupper($algorithm), $this->algos); |
||
113 | } |
||
114 | } |