/** * @param \Jose\Object\JWSInterface $jws * @param array $data */ private static function populatePayload(JWSInterface &$jws, array $data) { $is_encoded = null; foreach ($jws->getSignatures() as $signature) { if (null === $is_encoded) { $is_encoded = self::isPayloadEncoded($signature); } Assertion::eq($is_encoded, self::isPayloadEncoded($signature), 'Foreign payload encoding detected. The JWS cannot be loaded.'); } if (array_key_exists('payload', $data)) { $payload = $data['payload']; $jws = $jws->withAttachedPayload(); $jws = $jws->withEncodedPayload($payload); if (false !== $is_encoded) { $payload = Base64Url::decode($payload); } $json = json_decode($payload, true); if (null !== $json && !empty($payload)) { $payload = $json; } $jws = $jws->withPayload($payload); } else { $jws = $jws->withDetachedPayload(); } }
/** * {@inheritdoc} */ public function getCEK(JWKInterface $key, array $header) { if ('dir' !== $key->getKeyType()) { throw new \InvalidArgumentException('The key is not valid'); } return Base64Url::decode($key->getValue('dir')); }
/** * {@inheritdoc} */ public function getCEK(JWKInterface $key, array $header) { if (!$key->has('kty') || 'dir' !== $key->get('kty') || !$key->has('dir')) { throw new \InvalidArgumentException('The key is not valid'); } return Base64Url::decode($key->get('dir')); }
/** * @param JWKInterface $key */ protected function checkKey(JWKInterface $key) { parent::checkKey($key); if (24 !== strlen(Base64Url::decode($key->getValue('k')))) { throw new \InvalidArgumentException('The key size is not valid'); } }
/** * JWS constructor. * * @param string $input * @param string $signature * @param string|null $encoded_payload * @param string|null $payload * @param string|null $encoded_protected_header * @param array $unprotected_headers */ public function __construct($input, $signature, $encoded_payload = null, $payload = null, $encoded_protected_header = null, array $unprotected_headers = []) { $protected_header = empty($encoded_protected_header) ? [] : json_decode(Base64Url::decode($encoded_protected_header), true); parent::__construct($input, $protected_header, $unprotected_headers, $payload); $this->signature = $signature; $this->encoded_payload = $encoded_payload; $this->encoded_protected_header = $encoded_protected_header; }
/** * {@inheritdoc} */ public function getPublicIdFromSubjectIdentifier($subject_identifier) { $decoded = openssl_decrypt(Base64Url::decode($subject_identifier), $this->algorithm, $this->pairwise_encryption_key, OPENSSL_RAW_DATA, $this->iv); $parts = explode(':', $decoded); if (3 !== count($parts)) { return; } return $parts[1]; }
/** * @param \Jose\Object\JWKInterface $key */ protected function checkKey(JWKInterface $key) { if (!$key->has('kty') || 'oct' !== $key->get('kty') || !$key->has('k')) { throw new \InvalidArgumentException('The key is not valid'); } if ($this->getKeySize() !== strlen(Base64Url::decode($key->get('k')))) { throw new \InvalidArgumentException('The key size is not valid'); } }
/** * @see https://tools.ietf.org/html/rfc7517#appendix-C */ public function testPBES2HS256A128KW() { $header = ['alg' => 'PBES2-HS256+A128KW', 'p2s' => '2WCTcJZ1Rvd_CJuJripQ1w', 'p2c' => 4096, 'enc' => 'A128CBC-HS256', 'cty' => 'jwk+json']; $key = new JWK(['kty' => 'oct', 'k' => Base64Url::encode($this->convertArrayToBinString([84, 104, 117, 115, 32, 102, 114, 111, 109, 32, 109, 121, 32, 108, 105, 112, 115, 44, 32, 98, 121, 32, 121, 111, 117, 114, 115, 44, 32, 109, 121, 32, 115, 105, 110, 32, 105, 115, 32, 112, 117, 114, 103, 101, 100, 46]))]); $expected_cek = $this->convertArrayToBinString([111, 27, 25, 52, 66, 29, 20, 78, 92, 176, 56, 240, 65, 208, 82, 112, 161, 131, 36, 55, 202, 236, 185, 172, 129, 23, 153, 194, 195, 48, 253, 182]); $pbes2 = new PBES2HS256A128KW(); $wrapped_cek = Base64Url::decode('TrqXOwuNUfDV9VPTNbyGvEJ9JMjefAVn-TR1uIxR9p6hsRQh9Tk7BA'); $this->assertEquals($expected_cek, $pbes2->decryptKey($key, $wrapped_cek, $header)); }
/** * Key Derivation Function. * * @param string $Z Shared secret * @param string $algorithm Encryption algorithm * @param int $encryption_key_size Size of the encryption key * @param string $apu Agreement PartyUInfo (information about the producer) * @param string $apv Agreement PartyVInfo (information about the recipient) * * @return string */ public static function generate($Z, $algorithm, $encryption_key_size, $apu = '', $apv = '') { $apu = !empty($apu) ? Base64Url::decode($apu) : ''; $apv = !empty($apv) ? Base64Url::decode($apv) : ''; $encryption_segments = [self::toInt32Bits(1), $Z, self::toInt32Bits(mb_strlen($algorithm, '8bit')) . $algorithm, self::toInt32Bits(mb_strlen($apu, '8bit')) . $apu, self::toInt32Bits(mb_strlen($apv, '8bit')) . $apv, self::toInt32Bits($encryption_key_size), '']; $input = implode('', $encryption_segments); $hash = hash('sha256', $input, true); $kdf = mb_substr($hash, 0, $encryption_key_size / 8, '8bit'); return $kdf; }
/** * */ public function testES512Verify() { $public_key = new JWK(); $public_key->setValues(['kty' => 'EC', 'kid' => '*****@*****.**', 'use' => 'sig', 'crv' => 'P-521', 'x' => 'AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt', 'y' => 'AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1']); $header = 'eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9'; $payload = 'SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4'; $signature = 'AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2'; $ecdsa = new ES512(); $this->assertTrue($ecdsa->verify($public_key, $header . '.' . $payload, Base64Url::decode($signature))); }
/** * @param \Jose\Object\JWKInterface $key * @param string $encryted_cek * @param array $header * * @return mixed */ public function decryptKey(JWKInterface $key, $encryted_cek, array $header) { $this->checkKey($key); $this->checkAdditionalParameters($header); $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize()); $cipher->setTag(Base64Url::decode($header['tag'])); $cipher->setAAD(null); $cek = $cipher->decrypt($encryted_cek, Base64Url::decode($key->get('k')), Base64Url::decode($header['iv'])); return $cek; }
public static function handle_register() { if (isset($_POST['oldEndpoint']) && $_POST['oldEndpoint'] !== $_POST['endpoint']) { WebPush_DB::remove_subscription($_POST['oldEndpoint']); } WebPush_DB::add_subscription($_POST['endpoint'], isset($_POST['key']) ? $_POST['key'] : '', isset($_POST['auth']) ? Base64Url::decode($_POST['auth']) : ''); if (isset($_POST['newRegistration'])) { update_option('webpush_accepted_prompt_count', get_option('webpush_accepted_prompt_count') + 1); } wp_die(); }
/** * {@inheritdoc} */ public function verify(JWKInterface $key, $data, $signature) { $this->checkKey($key); $public = Base64Url::decode($key->get('x')); switch ($key->get('crv')) { case 'Ed25519': return ed25519_sign_open($data, $public, $signature); default: throw new \InvalidArgumentException('Unsupported curve'); } }
/** * JWE constructor. * * @param string $input * @param string $ciphertext * @param string|null $encrypted_key * @param string|null $iv * @param string|null $aad * @param string|null $tag * @param string|null $encoded_protected_header * @param array $unprotected_header * @param string|null $payload */ public function __construct($input, $ciphertext, $encrypted_key = null, $iv = null, $aad = null, $tag = null, $encoded_protected_header = null, $unprotected_header = [], $payload = null) { $protected_header = empty($encoded_protected_header) ? [] : json_decode(Base64Url::decode($encoded_protected_header), true); parent::__construct($input, $protected_header, $unprotected_header, $payload); $this->ciphertext = $ciphertext; $this->encrypted_key = $encrypted_key; $this->iv = $iv; $this->aad = $aad; $this->tag = $tag; $this->encoded_protected_header = $encoded_protected_header; }
/** * @param array $header * * @return \Jose\JWKInterface|null */ protected function findByAPV($header) { if (!isset($header['apv'])) { return; } if ('Bob' === Base64Url::decode($header['apv'])) { return $this->createJWK(['kty' => 'EC', 'crv' => 'P-256', 'x' => 'weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ', 'y' => 'e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck', 'd' => 'VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw']); } if ('Alice' === Base64Url::decode($header['apv'])) { return $this->createJWK(['kty' => 'EC', 'crv' => 'P-256', 'x' => 'gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0', 'y' => 'SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps', 'd' => '0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo']); } }
/** * {@inheritdoc} */ public function unwrapKey(JWKInterface $key, $encrypted_cek, array $header) { $this->checkKey($key); $this->checkHeaderAlgorithm($header); $this->checkHeaderAdditionalParameters($header); $wrapper = $this->getWrapper(); $hash_algorithm = $this->getHashAlgorithm(); $key_size = $this->getKeySize(); $salt = $header['alg'] . "" . Base64Url::decode($header['p2s']); $count = $header['p2c']; $password = Base64Url::decode($key->get('k')); $derived_key = hash_pbkdf2($hash_algorithm, $password, $salt, $count, $key_size, true); return $wrapper->unwrap($derived_key, $encrypted_cek); }
/** * @see https://tools.ietf.org/html/rfc7518#appendix-C */ public function testGetAgreementKey() { $receiver = new JWK(['kty' => 'EC', 'crv' => 'P-256', 'x' => 'weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ', 'y' => 'e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck', 'd' => 'VEmDZpDXXK8p8N0Cndsxs924q6nS1RXFASRl6BfUqdw']); $sender = new JWK(['kty' => 'EC', 'crv' => 'P-256', 'x' => 'gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0', 'y' => 'SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps', 'd' => '0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd']); $header = ['enc' => 'A128GCM', 'apu' => 'QWxpY2U', 'apv' => 'Qm9i']; $expected = Base64Url::decode('9FdsD3uzmeK4ImyoWpP5PA'); $ecdh_es = new ECDHES(); $additional_header_values = []; $this->assertEquals($expected, $ecdh_es->getAgreementKey(128, $sender, $receiver, $header, $additional_header_values)); $this->assertTrue(array_key_exists('epk', $additional_header_values)); $this->assertTrue(array_key_exists('kty', $additional_header_values['epk'])); $this->assertTrue(array_key_exists('crv', $additional_header_values['epk'])); $this->assertTrue(array_key_exists('x', $additional_header_values['epk'])); $this->assertTrue(array_key_exists('y', $additional_header_values['epk'])); }
/** * @see https://tools.ietf.org/html/rfc7516#appendix-A.1 */ public function testRSAOAEPEncryptionAndDecryption() { $header = []; $jwk = new JWK(['kty' => 'RSA', 'n' => 'oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUWcJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3Spsk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2asbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMStPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2djYgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw', 'e' => 'AQAB', 'd' => 'kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5NWV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD93Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghkqDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vlt3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSndVTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ', 'p' => '1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lffNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0', 'q' => 'wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBmUDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aXIWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc', 'dp' => 'ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KLhMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE', 'dq' => 'Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCjywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDBUfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis', 'qi' => 'VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY']); $cek = [177, 161, 244, 128, 84, 143, 225, 115, 63, 180, 3, 255, 107, 154, 212, 246, 138, 7, 110, 91, 112, 46, 34, 105, 47, 130, 203, 46, 122, 234, 64, 252]; foreach ($cek as $key => $value) { $cek[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT); } $cek = hex2bin(implode('', $cek)); $from_specification = Base64Url::decode('OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg'); $rsa_oaep = new RSAOAEP(); $encrypted = $rsa_oaep->encryptKey($jwk, $cek, $header); $this->assertEquals($cek, $rsa_oaep->decryptKey($jwk, $encrypted, $header)); $this->assertEquals($cek, $rsa_oaep->decryptKey($jwk, $from_specification, $header)); }
/** * {@inheritdoc} */ public function unwrapKey(JWKInterface $key, $encrypted_cek, array $header) { $this->checkKey($key); $this->checkAdditionalParameters($header); $kek = Base64Url::decode($key->get('k')); $tag = Base64Url::decode($header['tag']); $iv = Base64Url::decode($header['iv']); if (version_compare(PHP_VERSION, '7.1.0') >= 0) { return openssl_decrypt($encrypted_cek, $this->getMode($kek), $kek, OPENSSL_RAW_DATA, $iv, $tag, null); } elseif (class_exists('\\Crypto\\Cipher')) { $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize()); $cipher->setTag($tag); $cipher->setAAD(null); $cek = $cipher->decrypt($encrypted_cek, $kek, $iv); return $cek; } return AESGCM::decrypt($kek, $iv, $encrypted_cek, null, $tag); }
/** * @param \Jose\Object\JWEInterface $jwe * @param \Jose\Algorithm\ContentEncryptionAlgorithmInterface $content_encryption_algorithm * @param string $key_management_mode * @param array $additional_headers * * @return string */ private function determineCEK(Object\JWEInterface $jwe, Algorithm\ContentEncryptionAlgorithmInterface $content_encryption_algorithm, $key_management_mode, array &$additional_headers) { switch ($key_management_mode) { case Algorithm\KeyEncryption\KeyEncryptionInterface::MODE_ENCRYPT: case Algorithm\KeyEncryption\KeyEncryptionInterface::MODE_WRAP: return $this->createCEK($content_encryption_algorithm->getCEKSize()); case Algorithm\KeyEncryption\KeyEncryptionInterface::MODE_AGREEMENT: Assertion::eq(1, $jwe->countRecipients(), 'Unable to encrypt for multiple recipients using key agreement algorithms.'); $complete_headers = array_merge($jwe->getSharedProtectedHeaders(), $jwe->getSharedHeaders(), $jwe->getRecipient(0)->getHeaders()); $algorithm = $this->findKeyEncryptionAlgorithm($complete_headers); return $algorithm->getAgreementKey($content_encryption_algorithm->getCEKSize(), $content_encryption_algorithm->getAlgorithmName(), $jwe->getRecipient(0)->getRecipientKey(), $complete_headers, $additional_headers); case Algorithm\KeyEncryption\KeyEncryptionInterface::MODE_DIRECT: Assertion::eq(1, $jwe->countRecipients(), 'Unable to encrypt for multiple recipients using key agreement algorithms.'); Assertion::eq($jwe->getRecipient(0)->getRecipientKey()->get('kty'), 'oct', 'Wrong key type.'); Assertion::true($jwe->getRecipient(0)->getRecipientKey()->has('k'), 'The key parameter "k" is missing.'); return Base64Url::decode($jwe->getRecipient(0)->getRecipientKey()->get('k')); default: throw new \InvalidArgumentException(sprintf('Unsupported key management mode "%s".', $key_management_mode)); } }
/** * @param string $payload With padding * @param string $userPublicKey Base 64 encoded (MIME or URL-safe) * @param string $userAuthToken Base 64 encoded (MIME or URL-safe) * @param bool $nativeEncryption Use OpenSSL (>PHP7.1) * * @return array */ public static function encrypt($payload, $userPublicKey, $userAuthToken, $nativeEncryption) { $userPublicKey = Base64Url::decode($userPublicKey); $userAuthToken = Base64Url::decode($userAuthToken); // initialize utilities $math = EccFactory::getAdapter(); $pointSerializer = new UncompressedPointSerializer($math); $generator = EccFactory::getNistCurves()->generator256(); $curve = EccFactory::getNistCurves()->curve256(); // get local key pair $localPrivateKeyObject = $generator->createPrivateKey(); $localPublicKeyObject = $localPrivateKeyObject->getPublicKey(); $localPublicKey = hex2bin($pointSerializer->serialize($localPublicKeyObject->getPoint())); // get user public key object $pointUserPublicKey = $pointSerializer->unserialize($curve, bin2hex($userPublicKey)); $userPublicKeyObject = $generator->getPublicKeyFrom($pointUserPublicKey->getX(), $pointUserPublicKey->getY(), $generator->getOrder()); // get shared secret from user public key and local private key $sharedSecret = hex2bin($math->decHex(gmp_strval($userPublicKeyObject->getPoint()->mul($localPrivateKeyObject->getSecret())->getX()))); // generate salt $salt = openssl_random_pseudo_bytes(16); // section 4.3 $ikm = !empty($userAuthToken) ? self::hkdf($userAuthToken, $sharedSecret, 'Content-Encoding: auth' . chr(0), 32) : $sharedSecret; // section 4.2 $context = self::createContext($userPublicKey, $localPublicKey); // derive the Content Encryption Key $contentEncryptionKeyInfo = self::createInfo('aesgcm', $context); $contentEncryptionKey = self::hkdf($salt, $ikm, $contentEncryptionKeyInfo, 16); // section 3.3, derive the nonce $nonceInfo = self::createInfo('nonce', $context); $nonce = self::hkdf($salt, $ikm, $nonceInfo, 12); // encrypt // "The additional data passed to each invocation of AEAD_AES_128_GCM is a zero-length octet sequence." if (!$nativeEncryption) { list($encryptedText, $tag) = \AESGCM\AESGCM::encrypt($contentEncryptionKey, $nonce, $payload, ''); } else { $encryptedText = openssl_encrypt($payload, 'aes-128-gcm', $contentEncryptionKey, OPENSSL_RAW_DATA, $nonce, $tag); // base 64 encoded } // return values in url safe base64 return array('localPublicKey' => Base64Url::encode($localPublicKey), 'salt' => Base64Url::encode($salt), 'cipherText' => $encryptedText . $tag); }
/** * @param array $vapid * * @return array * * @throws \ErrorException */ public static function validate(array $vapid) { if (!array_key_exists('subject', $vapid)) { throw new \ErrorException('[VAPID] You must provide a subject that is either a mailto: or a URL.'); } if (array_key_exists('pemFile', $vapid)) { $vapid['pem'] = file_get_contents($vapid['pemFile']); if (!$vapid['pem']) { throw new \ErrorException('Error loading PEM file.'); } } if (array_key_exists('pem', $vapid)) { $pem = $vapid['pem']; $posStartKey = strpos($pem, '-----BEGIN EC PRIVATE KEY-----'); $posEndKey = strpos($pem, '-----END EC PRIVATE KEY-----'); if ($posStartKey === false || $posEndKey === false) { throw new \ErrorException('Invalid PEM data.'); } $posStartKey += 30; // length of '-----BEGIN EC PRIVATE KEY-----' $pemSerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer()); $keys = self::getUncompressedKeys($pemSerializer->parse(substr($pem, $posStartKey, $posEndKey - $posStartKey))); $vapid['publicKey'] = $keys['publicKey']; $vapid['privateKey'] = $keys['privateKey']; } if (!array_key_exists('publicKey', $vapid)) { throw new \ErrorException('[VAPID] You must provide a public key.'); } $publicKey = Base64Url::decode($vapid['publicKey']); if (Utils::safeStrlen($publicKey) !== self::PUBLIC_KEY_LENGTH) { throw new \ErrorException('[VAPID] Public key should be 65 bytes long when decoded.'); } if (!array_key_exists('privateKey', $vapid)) { throw new \ErrorException('[VAPID] You must provide a private key.'); } $privateKey = Base64Url::decode($vapid['privateKey']); if (Utils::safeStrlen($privateKey) !== self::PRIVATE_KEY_LENGTH) { throw new \ErrorException('[VAPID] Private key should be 32 bytes long when decoded.'); } return array('subject' => $vapid['subject'], 'publicKey' => $publicKey, 'privateKey' => $privateKey); }
/** * @param array $data * * @return null|string */ private static function getRecipientEncryptedKey(array $data) { if (array_key_exists('encrypted_key', $data)) { return Base64Url::decode($data['encrypted_key']); } }
private function initPrivateKey() { $this->addChild(new Integer(1)); $this->addChild(new OctetString(bin2hex(Base64Url::decode($this->values['d'])))); $oid = new ObjectIdentifier($this->getOID($this->values['crv'])); $this->addChild(new ExplicitlyTaggedObject(0, $oid)); $bits = '04'; $bits .= bin2hex(Base64Url::decode($this->values['x'])); $bits .= bin2hex(Base64Url::decode($this->values['y'])); $bit = new BitString($bits); $this->addChild(new ExplicitlyTaggedObject(1, $bit)); }
/** * @param \Jose\Object\JWKInterface $key */ protected function checkKey(JWKInterface $key) { Assertion::eq($key->get('kty'), 'oct', 'Wrong key type.'); Assertion::true($key->has('k'), 'The key parameter "k" is missing.'); Assertion::eq($this->getKeySize(), mb_strlen(Base64Url::decode($key->get('k')), '8bit'), 'The key size is not valid'); }
/** * @param string $value * * @return resource */ private function convertBase64ToGmp($value) { $value = unpack('H*', Base64Url::decode($value)); return gmp_init($value[1], 16); }
/** * {@inheritdoc} */ public function sign(JWKInterface $key, $input) { $this->checkKey($key); return hex2bin(hash_hmac($this->getHashAlgorithm(), $input, Base64Url::decode($key->getValue('k')))); }
/** * @param $value * * @return int|string */ private function convertBase64ToDec($value) { $value = unpack('H*', Base64Url::decode($value)); return $this->convertHexToDec($value[1]); }
protected function parseResponse($response) { $obj = json_decode($response); if ($obj === false) { //TODO throw an exception return array('error'); } $arr = explode('.', $obj->token); if (sizeof($arr) != 3) { //TODO throw an exception } return array('header' => \Base64Url\Base64Url::decode($arr[0]), 'payload' => \Base64Url\Base64Url::decode($arr[1]), 'signature' => \Base64Url\Base64Url::decode($arr[2])); }
/** * @param array $recipient * @param array $complete_header * @param \Jose\JWKSetInterface $jwk_set * * @return string|null */ protected function decryptCEK(array $recipient, array $complete_header, JWKSetInterface $jwk_set = null) { $encrypted_key = array_key_exists('encrypted_key', $recipient) ? Base64Url::decode($recipient['encrypted_key']) : null; $this->checkCompleteHeader($complete_header); $keys = $jwk_set; if (is_null($keys)) { $keys = $this->getKeysFromCompleteHeader($complete_header); } $key_encryption_algorithm = $this->getKeyEncryptionAlgorithm($complete_header['alg']); $content_encryption_algorithm = $this->getContentEncryptionAlgorithm($complete_header['enc']); foreach ($keys as $key) { if (!$this->checkKeyUsage($key, 'decryption')) { continue; } $cek = $this->getCEK($key_encryption_algorithm, $content_encryption_algorithm, $key, $encrypted_key, $complete_header); if (!is_null($cek)) { return $cek; } } }