Source of file Rsa.php
Size: 9,747 Bytes - Last Modified: 2014-03-12T23:21:18+01:00
/home/theseer/Downloads/ZendFramework-2.3.0/library/Zend/Crypt/PublicKey/Rsa.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 | <?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; } } |