- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
- namespace Zend\Crypt\PublicKey;
-
- use Traversable;
- use Zend\Crypt\PublicKey\Rsa\Exception;
- use Zend\Stdlib\ArrayUtils;
-
- /**
- * Implementation of the RSA public key encryption algorithm.
- */
- class Rsa
- {
- const MODE_AUTO = 1;
- const MODE_BASE64 = 2;
- const MODE_RAW = 3;
-
- /**
- * @var RsaOptions
- */
- protected $options = null;
-
- /**
- * RSA instance factory
- *
- * @param array|Traversable $options
- * @return Rsa
- * @throws Rsa\Exception\RuntimeException
- * @throws Rsa\Exception\InvalidArgumentException
- */
- public static function factory($options)
- {
- if (!extension_loaded('openssl')) {
- throw new Exception\RuntimeException(
- 'Can not create Zend\Crypt\PublicKey\Rsa; openssl extension to be loaded'
- );
- }
-
- if ($options instanceof Traversable) {
- $options = ArrayUtils::iteratorToArray($options);
- } elseif (!is_array($options)) {
- throw new Exception\InvalidArgumentException(
- 'The options parameter must be an array or a Traversable'
- );
- }
-
- $privateKey = null;
- $passPhrase = isset($options['pass_phrase']) ? $options['pass_phrase'] : null;
- if (isset($options['private_key'])) {
- if (is_file($options['private_key'])) {
- $privateKey = Rsa\PrivateKey::fromFile($options['private_key'], $passPhrase);
- } elseif (is_string($options['private_key'])) {
- $privateKey = new Rsa\PrivateKey($options['private_key'], $passPhrase);
- } else {
- throw new Exception\InvalidArgumentException(
- 'Parameter "private_key" must be PEM formatted string or path to key file'
- );
- }
- unset($options['private_key']);
- }
-
- $publicKey = null;
- if (isset($options['public_key'])) {
- if (is_file($options['public_key'])) {
- $publicKey = Rsa\PublicKey::fromFile($options['public_key']);
- } elseif (is_string($options['public_key'])) {
- $publicKey = new Rsa\PublicKey($options['public_key']);
- } else {
- throw new Exception\InvalidArgumentException(
- 'Parameter "public_key" must be PEM/certificate string or path to key/certificate file'
- );
- }
- unset($options['public_key']);
- }
-
- $options = new RsaOptions($options);
- if ($privateKey instanceof Rsa\PrivateKey) {
- $options->setPrivateKey($privateKey);
- }
- if ($publicKey instanceof Rsa\PublicKey) {
- $options->setPublicKey($publicKey);
- }
-
- return new Rsa($options);
- }
-
- /**
- * Class constructor
- *
- * @param RsaOptions $options
- * @throws Rsa\Exception\RuntimeException
- */
- public function __construct(RsaOptions $options = null)
- {
- if (!extension_loaded('openssl')) {
- throw new Exception\RuntimeException(
- 'Zend\Crypt\PublicKey\Rsa requires openssl extension to be loaded'
- );
- }
-
- if ($options === null) {
- $this->options = new RsaOptions();
- } else {
- $this->options = $options;
- }
- }
-
- /**
- * Set options
- *
- * @param RsaOptions $options
- * @return Rsa
- */
- public function setOptions(RsaOptions $options)
- {
- $this->options = $options;
- return $this;
- }
-
- /**
- * Get options
- *
- * @return RsaOptions
- */
- public function getOptions()
- {
- return $this->options;
- }
-
- /**
- * Return last openssl error(s)
- *
- * @return string
- */
- public function getOpensslErrorString()
- {
- $message = '';
- while (false !== ($error = openssl_error_string())) {
- $message .= $error . "\n";
- }
- return trim($message);
- }
-
- /**
- * Sign with private key
- *
- * @param string $data
- * @param Rsa\PrivateKey $privateKey
- * @return string
- * @throws Rsa\Exception\RuntimeException
- */
- public function sign($data, Rsa\PrivateKey $privateKey = null)
- {
- $signature = '';
- if (null === $privateKey) {
- $privateKey = $this->options->getPrivateKey();
- }
-
- $result = openssl_sign(
- $data,
- $signature,
- $privateKey->getOpensslKeyResource(),
- $this->options->getOpensslSignatureAlgorithm()
- );
- if (false === $result) {
- throw new Exception\RuntimeException(
- 'Can not generate signature; openssl ' . $this->getOpensslErrorString()
- );
- }
-
- if ($this->options->getBinaryOutput()) {
- return $signature;
- }
-
- return base64_encode($signature);
- }
-
- /**
- * Verify signature with public key
- *
- * $signature can be encoded in base64 or not. $mode sets how the input must be processed:
- * - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
- * - MODE_BASE64: Decode $signature using base64 algorithm.
- * - MODE_RAW: $signature is not encoded.
- *
- * @param string $data
- * @param string $signature
- * @param null|Rsa\PublicKey $publicKey
- * @param int $mode Input encoding
- * @return bool
- * @throws Rsa\Exception\RuntimeException
- * @see Rsa::MODE_AUTO
- * @see Rsa::MODE_BASE64
- * @see Rsa::MODE_RAW
- */
- public function verify(
- $data,
- $signature,
- Rsa\PublicKey $publicKey = null,
- $mode = self::MODE_AUTO
- ) {
- if (null === $publicKey) {
- $publicKey = $this->options->getPublicKey();
- }
-
- switch ($mode) {
- case self::MODE_AUTO:
- // check if data is encoded in Base64
- $output = base64_decode($signature, true);
- if ((false !== $output) && ($signature === base64_encode($output))) {
- $signature = $output;
- }
- break;
- case self::MODE_BASE64:
- $signature = base64_decode($signature);
- break;
- case self::MODE_RAW:
- default:
- break;
- }
-
- $result = openssl_verify(
- $data,
- $signature,
- $publicKey->getOpensslKeyResource(),
- $this->options->getOpensslSignatureAlgorithm()
- );
- if (-1 === $result) {
- throw new Exception\RuntimeException(
- 'Can not verify signature; openssl ' . $this->getOpensslErrorString()
- );
- }
-
- return ($result === 1);
- }
-
- /**
- * Encrypt with private/public key
- *
- * @param string $data
- * @param Rsa\AbstractKey $key
- * @return string
- * @throws Rsa\Exception\InvalidArgumentException
- */
- public function encrypt($data, Rsa\AbstractKey $key = null)
- {
- if (null === $key) {
- $key = $this->options->getPublicKey();
- }
-
- if (null === $key) {
- throw new Exception\InvalidArgumentException('No key specified for the decryption');
- }
-
- $encrypted = $key->encrypt($data);
-
- if ($this->options->getBinaryOutput()) {
- return $encrypted;
- }
-
- return base64_encode($encrypted);
- }
-
- /**
- * Decrypt with private/public key
- *
- * $data can be encoded in base64 or not. $mode sets how the input must be processed:
- * - MODE_AUTO: Check if the $signature is encoded in base64. Not recommended for performance.
- * - MODE_BASE64: Decode $data using base64 algorithm.
- * - MODE_RAW: $data is not encoded.
- *
- * @param string $data
- * @param Rsa\AbstractKey $key
- * @param int $mode Input encoding
- * @return string
- * @throws Rsa\Exception\InvalidArgumentException
- * @see Rsa::MODE_AUTO
- * @see Rsa::MODE_BASE64
- * @see Rsa::MODE_RAW
- */
- public function decrypt(
- $data,
- Rsa\AbstractKey $key = null,
- $mode = self::MODE_AUTO
- ) {
- if (null === $key) {
- $key = $this->options->getPrivateKey();
- }
-
- if (null === $key) {
- throw new Exception\InvalidArgumentException('No key specified for the decryption');
- }
-
- switch ($mode) {
- case self::MODE_AUTO:
- // check if data is encoded in Base64
- $output = base64_decode($data, true);
- if ((false !== $output) && ($data === base64_encode($output))) {
- $data = $output;
- }
- break;
- case self::MODE_BASE64:
- $data = base64_decode($data);
- break;
- case self::MODE_RAW:
- default:
- break;
- }
-
- return $key->decrypt($data);
- }
-
- /**
- * Generate new private/public key pair
- * @see RsaOptions::generateKeys()
- *
- * @param array $opensslConfig
- * @return Rsa
- * @throws Rsa\Exception\RuntimeException
- */
- public function generateKeys(array $opensslConfig = array())
- {
- $this->options->generateKeys($opensslConfig);
- return $this;
- }
- }
# |
Change |
User |
Description |
Committed |
|
#1
|
18334 |
Liz Lam |
initial add of jambox |
9 years ago
|
|