/** * @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 createECKey(array $values) { Assertion::keyExists($values, 'crv', 'The curve is not set.'); $curve = $values['crv']; if (function_exists('openssl_get_curve_names')) { $args = ['curve_name' => self::getOpensslName($curve), 'private_key_type' => OPENSSL_KEYTYPE_EC]; $key = openssl_pkey_new($args); $res = openssl_pkey_export($key, $out); Assertion::true($res, 'Unable to create the key'); $rsa = new ECKey($out); $values = array_merge($values, $rsa->toArray()); return new JWK($values); } else { $curve_name = self::getNistName($curve); $generator = CurveFactory::getGeneratorByName($curve_name); $private_key = $generator->createPrivateKey(); $values = array_merge($values, ['kty' => 'EC', 'crv' => $curve, 'x' => self::encodeValue($private_key->getPublicKey()->getPoint()->getX()), 'y' => self::encodeValue($private_key->getPublicKey()->getPoint()->getY()), 'd' => self::encodeValue($private_key->getSecret())]); } return new JWK($values); }
/** * @param string $pem * @param null|string $password * * @throws \Exception * * @return array */ public static function loadKeyFromPEM($pem, $password = null) { if (preg_match('#DEK-Info: (.+),(.+)#', $pem, $matches)) { $pem = self::decodePEM($pem, $matches, $password); } $res = openssl_pkey_get_private($pem); if ($res === false) { $res = openssl_pkey_get_public($pem); } if ($res === false) { throw new \InvalidArgumentException('Unable to load the key'); } $details = openssl_pkey_get_details($res); if (!is_array($details) || !array_key_exists('type', $details)) { throw new \Exception('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: $temp = ['kty' => 'RSA']; foreach (['n' => 'n', 'e' => 'e', 'd' => 'd', 'p' => 'p', 'q' => 'q', 'dp' => 'dmp1', 'dq' => 'dmq1', 'qi' => 'iqmp'] as $A => $B) { if (array_key_exists($B, $details['rsa'])) { $temp[$A] = Base64Url::encode($details['rsa'][$B]); } } return $temp; /* * The following lines will be used when FGrosse/PHPASN1 v1.4.0 will be available * (not available because of current version of mdanter/phpecc. * $rsa_key = new RSAKey($pem); * * return $rsa_key->toArray(); */ /* * The following lines will be used when FGrosse/PHPASN1 v1.4.0 will be available * (not available because of current version of mdanter/phpecc. * $rsa_key = new RSAKey($pem); * * return $rsa_key->toArray(); */ default: throw new \InvalidArgumentException('Unsupported key type'); } }
/** * @param \Jose\Object\JWKInterface $key * @param string $data * @param string $R * @param string $S * * @return bool */ private function verifyOpenSSLSignature(JWKInterface $key, $data, $R, $S) { $pem = ECKey::toPublic(new ECKey($key))->toPEM(); $oid_sequence = new Sequence(); $oid_sequence->addChildren([new Integer(gmp_strval($this->convertHexToGmp($R), 10)), new Integer(gmp_strval($this->convertHexToGmp($S), 10))]); return 1 === openssl_verify($data, $oid_sequence->getBinary(), $pem, $this->getHashAlgorithm()); }
/** * @param \Jose\KeyConverter\ECKey $private * * @return \Jose\KeyConverter\ECKey */ public static function toPublic(ECKey $private) { $data = $private->toArray(); if (array_key_exists('d', $data)) { unset($data['d']); } return new self($data); }