Subversion Repositories oidplus

Rev

Rev 868 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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);
  103.                 return hash_equals(hash_hmac($this->algos[$d["alg"]], $d["h"] . "." . $d["p"], $this->secretKey, true), $d["sig"]);
  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. }
  115.