Пример #1
2
 public function testDecrypt()
 {
     $plaintext = 'Live long and prosper.';
     $token = 'eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ.AxY8DCtDaGlsbGljb3RoZQ.KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.U0m_YmjN04DJvceFICbCVQ';
     $private_set = $this->getPrivateKeySet();
     $test_jwe = JWE::decrypt($token, $private_set, 'A128KW');
     $this->assertEquals($plaintext, $test_jwe->getPlaintext());
 }
Пример #2
0
 /**
  * Decrypts and verifies a nested JWT.
  *
  * If the supplied token is a JWT, this function calls {@link getObject()}
  * to decode the JWT.
  *
  * If the supplied token is a JWE, the JWE is firstly decrypted, then the underlying
  * plaintext is treated as a JWT, and further decoded.
  *
  * @param SimpleJWT\Keys\KeySet $keys the key set containing the decryption
  * and verification keys
  * @param string $expected_jwe_alg the expected value of the `alg` parameter for the
  * JWE, which should be agreed between the parties out-of-band
  * @param string $expected_jwt_alg the expected value of the `alg` parameter for the
  * underlying JWT, which should be agreed between the parties out-of-band
  * @param string $jwe_kid the ID of the key to use for decryption. If null, this
  * is automatically retrieved
  * @param string $jwt_kid the ID of the key to use for verification. If null, this
  * is automatically retrieved
  * @return JWT the decoded JWT
  * @throws InvalidTokenException if the token is invalid for any reason
  */
 function getJWTObject($keys, $expected_jwe_alg, $expected_jwt_alg, $jwe_kid = null, $jwt_kid = null)
 {
     switch ($this->type) {
         case 'JWT':
             return $this->getObject($keys, $expected_jwt_alg, $jwt_kid);
         case 'JWE':
             $jwe = JWE::decrypt($this->data, $keys, $expected_jwe_alg, $jwe_kid, $this->format);
             if ($jwe->getHeader('cty') != 'JWT') {
                 throw new InvalidTokenException('Not a nested JWT', InvalidTokenException::TOKEN_PARSE_ERROR);
             }
             return JWT::decode($jwe->getPlaintext(), $keys, $expected_jwt_alg, $jwt_kid);
     }
 }
Пример #3
0
 /**
  * Builds the JOSE response.  This will return one of the following:
  *
  * - A JSON encoded string, if {@link $signed_response_alg} and
  *   {@link $encrypted_response_alg} are both null
  * - A signed JWT (JWS), if {@link $signed_response_alg} is set
  * - A JWE containing a nested JWT, if both {@link $signed_response_alg}
  *   and {@link $encrypted_response_alg} are set
  *
  * @param SimpleJWT\Keys\KeySet $set the key set used to sign and/or
  * encrypt the token.  If set to null, the default set of keys
  * configured for the client and the server are loaded
  * @return string the response body
  */
 function buildJOSE($set = null)
 {
     $rand = new Random();
     $typ = $this->getType();
     if ($typ == 'json') {
         return json_encode($this->container);
     }
     if ($set == null) {
         $builder = new KeySetBuilder($client);
         $set = $builder->addClientSecret()->addClientPublicKeys()->addServerPrivateKeys()->toKeySet();
     }
     $headers = array_merge($this->headers, array('alg' => $this->signed_response_alg));
     $claims = array_merge($this->container, array('iss' => $this->issuer, 'aud' => $this->client->getStoreID(), 'jti' => $rand->id()));
     $jwt = new JWT($headers, $claims);
     try {
         $token = $jwt->encode($set);
     } catch (CryptException $e) {
         return null;
     }
     if ($typ == 'jwt') {
         return $token;
     }
     $headers = array('alg' => $this->encrypted_response_alg, 'enc' => $this->encrypted_response_enc, 'cty' => 'JWT');
     $jwe = new JWE($headers, $token);
     try {
         return $jwe->encrypt($set);
     } catch (CryptException $e) {
         return null;
     }
 }
Пример #4
0
 /**
  * Detects the format of key data and returns a key object.
  *
  * The supported formats are:
  *
  * - `php` - JSON web key formatted as a PHP associative array
  * - `json` - JSON web key
  * - `pem` - the public or private key encoded in PEM (base64 encoded DER) format
  * - `jwe` - Encrypted JSON web key
  *
  * @param string $data the key data
  * @param string $format the format
  * @param string $password the password, if the key is password protected
  * @param string $alg the algorithm, if the key is password protected
  * @return Key the key object
  * @throws KeyException if an error occurs in reading the data
  */
 public static function create($data, $format = null, $password = null, $alg = 'PBES2-HS256+A128KW')
 {
     // 1. Detect format
     if ($format == null || $format == 'auto') {
         if (is_array($data)) {
             $format = 'php';
         } elseif (json_decode($data, true) != null) {
             $format = 'json';
         } elseif (substr_count($data, '.') == 5) {
             $format = 'jwe';
         } elseif (preg_match('/-----([^-:]+)-----/', $data)) {
             $format = 'pem';
         }
     }
     if ($format == null || $format == 'auto') {
         throw new KeyException('Cannot detect key format');
     }
     // 2. Decode JSON
     if ($format == 'json') {
         $json = json_decode($data, true);
         if (isset($json['ciphertext'])) {
             $format = 'jwe';
         } else {
             $data = $json;
             $format = 'php';
         }
     }
     // 3. JWE
     if ($format == 'jwe') {
         if ($password == null) {
             throw new KeyException('No password for encrypted key');
         } else {
             $keys = KeySet::createFromSecret($password, 'bin');
             try {
                 $jwe = JWE::decrypt($data, $keys, $alg, isset($data['ciphertext']) ? JWE::JSON_FORMAT : JWE::COMPACT_FORMAT);
                 $data = json_decode($jwe->getPlaintext());
                 $format = 'php';
             } catch (CryptException $e) {
                 throw new KeyException('Cannot decrypt key', 0, $e);
             }
         }
     }
     // 4. PHP/JSON
     if ($format == 'php') {
         if ($data != null && isset($data['kty'])) {
             if (isset(self::$jwk_kty_map[$data['kty']])) {
                 return new self::$jwk_kty_map[$data['kty']]($data, 'php');
             }
         }
     }
     // 4. PEM
     if ($format == 'pem') {
         if (preg_match(Key::PEM_PUBLIC, $data, $matches)) {
             $der = base64_decode($matches[1]);
             if ($der === FALSE) {
                 throw new KeyException('Cannot read PEM key');
             }
             $offset = 0;
             $offset += ASN1::readDER($der, $offset, $value);
             // SEQUENCE
             $offset += ASN1::readDER($der, $offset, $value);
             // SEQUENCE
             $offset += ASN1::readDER($der, $offset, $algorithm);
             // OBJECT IDENTIFIER - AlgorithmIdentifier
             $oid = ASN1::decodeOID($algorithm);
             if (isset(self::$oid_map[$oid])) {
                 return new self::$oid_map[$oid]($data, 'pem');
             }
         } else {
             foreach (self::$pem_map as $regex => $cls) {
                 if (preg_match($regex, $data)) {
                     return new $cls($data, 'pem');
                 }
             }
         }
     }
     // 5. Symmetric key
     if ($format == 'base64url' || $format == 'base64' || $format == 'bin') {
         return new SymmetricKey($data, $format);
     }
     return null;
 }
Пример #5
0
 /**
  * Returns a key set as a JSON web key set.
  *
  * If `$password` is null, an unencrypted JSON structure is returned.
  *
  * If `$password` is not null, a JWE is created using PBES2 key encryption.
  *
  * @param string $password the password
  * @return string the key set
  */
 function toJWKS($password = null)
 {
     $result = array_map(function ($key) {
         return $key->getKeyData();
     }, $this->keys);
     $json = json_encode(array('keys' => $result));
     if ($password == null) {
         return $json;
     }
     $keys = KeySet::createFromSecret($password, 'bin');
     $headers = array('alg' => 'PBES2-HS256+A128KW', 'enc' => 'A128CBC-HS256', 'cty' => 'jwk-set+json');
     $jwe = new JWE($headers, $json);
     return $jwe->encrypt($keys);
 }
Пример #6
0
 /**
  * Returns a key as a JSON web key.
  *
  * If `$password` is null or if the key is a public key, an unencrypted JSON
  * structure is returned.
  *
  * If `$password` is not null and the key is a private key, a JWE is created
  * using PBES2 key encryption.
  *
  * @param string $password the password
  * @return string the key set
  */
 public function toJWK($password = null)
 {
     $json = json_encode($this->data);
     if ($password == null || $this->isPublic()) {
         return $json;
     }
     $keys = KeySet::createFromSecret($password, 'bin');
     $headers = array('alg' => 'PBES2-HS256+A128KW', 'enc' => 'A128CBC-HS256', 'cty' => 'jwk+json');
     $jwe = new JWE($headers, $json);
     return $jwe->encrypt($keys);
 }