/** * {@inheritdoc} */ public function verify(JWKInterface $key, $input, $signature) { $this->checkKey($key); $pub = RSAKey::toPublic(new RSAKey($key)); if ($this->getSignatureMethod() === self::SIGNATURE_PSS) { return JoseRSA::verify($pub, $input, $signature, $this->getAlgorithm()); } else { return 1 === openssl_verify($input, $signature, $pub->toPEM(), $this->getAlgorithm()); } }
/** * {@inheritdoc} */ public function encryptKey(JWKInterface $key, $cek, array $complete_headers, array &$additional_headers) { $this->checkKey($key); $pub = RSAKey::toPublic(new RSAKey($key)); if (self::ENCRYPTION_OAEP === $this->getEncryptionMode()) { $encrypted = JoseRSA::encrypt($pub, $cek, $this->getHashAlgorithm()); Assertion::string($encrypted, 'Unable to encrypt the data.'); return $encrypted; } else { $res = openssl_public_encrypt($cek, $encrypted, $pub->toPEM(), OPENSSL_PKCS1_PADDING | OPENSSL_RAW_DATA); Assertion::true($res, 'Unable to encrypt the data.'); return $encrypted; } }
/** * @param string $pem * @param null|string $password * * @throws \Exception * * @return array */ private static function loadKeyFromPEM($pem, $password = null) { if (preg_match('#DEK-Info: (.+),(.+)#', $pem, $matches)) { $pem = self::decodePem($pem, $matches, $password); } self::sanitizePEM($pem); $res = openssl_pkey_get_private($pem); if ($res === false) { $res = openssl_pkey_get_public($pem); } Assertion::false($res === false, 'Unable to load the key'); $details = openssl_pkey_get_details($res); Assertion::isArray($details, 'Unable to get details of the key'); Assertion::keyExists($details, 'type', 'Unable to get details of the key'); switch ($details['type']) { case OPENSSL_KEYTYPE_EC: $ec_key = new ECKey($pem); return $ec_key->toArray(); case OPENSSL_KEYTYPE_RSA: $rsa_key = new RSAKey($pem); return $rsa_key->toArray(); default: throw new \InvalidArgumentException('Unsupported key type'); } }
/** * {@inheritdoc} */ public static function createRSAKey(array $values) { Assertion::keyExists($values, 'size', 'The key size is not set.'); $size = $values['size']; unset($values['size']); Assertion::true(0 === $size % 8, 'Invalid key size.'); Assertion::greaterOrEqualThan($size, 384, 'Key length is too short. It needs to be at least 384 bits.'); $key = openssl_pkey_new(['private_key_bits' => $size, 'private_key_type' => OPENSSL_KEYTYPE_RSA]); openssl_pkey_export($key, $out); $rsa = new RSAKey($out); $values = array_merge($values, $rsa->toArray()); return new JWK($values); }
/** * Verifies a signature. * * @param \Jose\KeyConverter\RSAKey $key * @param string $message * @param string $signature * @param string $hash * * @return bool */ public static function verify(RSAKey $key, $message, $signature, $hash) { Assertion::string($message); Assertion::string($signature); Assertion::string($hash); Assertion::inArray($hash, ['sha256', 'sha384', 'sha512']); Assertion::eq(strlen($signature), $key->getModulusLength()); $modBits = 8 * $key->getModulusLength(); $s2 = self::convertOctetStringToInteger($signature); $m2 = self::getRSAVP1($key, $s2); Assertion::isInstanceOf($m2, BigInteger::class); $em = self::convertIntegerToOctetString($m2, $modBits >> 3); return self::verifyEMSAPSS($message, $em, $modBits - 1, Hash::$hash()); }
/** * @param \Jose\KeyConverter\RSAKey $private * * @return \Jose\KeyConverter\RSAKey */ public static function toPublic(RSAKey $private) { $data = $private->toArray(); $keys = ['p', 'd', 'q', 'dp', 'dq', 'qi']; foreach ($keys as $key) { if (array_key_exists($key, $data)) { unset($data[$key]); } } return new self($data); }