* Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
* Here's an example of how to encrypt and decrypt text with this library:
* include 'Crypt/RSA.php';
* $rsa = new Crypt_RSA();
* extract($rsa->createKey());
* $plaintext = 'terrafrost';
* $rsa->loadKey($privatekey);
* $ciphertext = $rsa->encrypt($plaintext);
* $rsa->loadKey($publickey);
* echo $rsa->decrypt($ciphertext);
* Here's an example of how to create signatures and verify signatures with this library:
* include 'Crypt/RSA.php';
* $rsa = new Crypt_RSA();
* extract($rsa->createKey());
* $plaintext = 'terrafrost';
* $rsa->loadKey($privatekey);
* $signature = $rsa->sign($plaintext);
* $rsa->loadKey($publickey);
* echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
* LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* @author Jim Wigginton <terrafrost@php.net>
* @copyright MMIX Jim Wigginton
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link http://phpseclib.sourceforge.net
// the class_exists() will only be called if the crypt_random_string function hasn't been defined and
// will trigger a call to __autoload() if you're wanting to auto-load classes
// call function_exists() a second time to stop the require_once from being called outside
if (!function_exists('crypt_random_string')) {
require_once dirname(__FILE__).'/Random.php';
if (!class_exists('Crypt_Hash')) {
require_once dirname(__FILE__).'/Hash.php';
* @see Crypt_RSA::encrypt()
* @see Crypt_RSA::decrypt()
* Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
* (OAEP) for encryption / decryption.
* @see Crypt_RSA::setHash()
* @see Crypt_RSA::setMGFHash()
define('CRYPT_RSA_ENCRYPTION_OAEP', 1);
* Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
* compatibility with protocols (like SSH-1) written before OAEP's introduction.
define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
* @see Crypt_RSA::verify()
* @see Crypt_RSA::setHash()
* Use the Probabilistic Signature Scheme for signing
* @see Crypt_RSA::setSaltLength()
* @see Crypt_RSA::setMGFHash()
define('CRYPT_RSA_SIGNATURE_PSS', 1);
* Use the PKCS#1 scheme by default.
* Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
* compatibility with protocols (like SSH-2) written before PSS's introduction.
define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
* @see Crypt_RSA::createKey()
define('CRYPT_RSA_ASN1_INTEGER', 2);
define('CRYPT_RSA_ASN1_BITSTRING', 3);
define('CRYPT_RSA_ASN1_OCTETSTRING', 4);
define('CRYPT_RSA_ASN1_OBJECT', 6);
* ASN1 Sequence (with the constucted bit set)
define('CRYPT_RSA_ASN1_SEQUENCE', 48);
* @see Crypt_RSA::Crypt_RSA()
* To use the pure-PHP implementation
define('CRYPT_RSA_MODE_INTERNAL', 1);
* To use the OpenSSL library
* (if enabled; otherwise, the internal implementation will be used)
define('CRYPT_RSA_MODE_OPENSSL', 2);
* Default openSSL configuration file.
define('CRYPT_RSA_OPENSSL_CONFIG', dirname(__FILE__).'/../openssl.cnf');
* @see Crypt_RSA::createKey()
* @see Crypt_RSA::setPrivateKeyFormat()
* PKCS#1 formatted private key
define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);
* PuTTY formatted private key
define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1);
* XML formatted private key
define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
* PKCS#8 formatted private key
define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3);
* @see Crypt_RSA::createKey()
* @see Crypt_RSA::setPublicKeyFormat()
* An array containing two Math_BigInteger objects.
* The exponent can be indexed with any of the following:
* 0, e, exponent, publicExponent
* The modulus can be indexed with any of the following:
define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3);
* PKCS#1 formatted public key (raw)
* Has the following header:
* -----BEGIN RSA PUBLIC KEY-----
* Analogous to ssh-keygen's pem format (as specified by -m)
define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4);
define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW', 4);
* XML formatted public key
define('CRYPT_RSA_PUBLIC_FORMAT_XML', 5);
* OpenSSH formatted public key
* Place in $HOME/.ssh/authorized_keys
define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6);
* PKCS#1 formatted public key (encapsulated)
* Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
* Has the following header:
* -----BEGIN PUBLIC KEY-----
* Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
* is specific to private keys it's basically creating a DER-encoded wrapper
* for keys. This just extends that same concept to public keys (much like ssh-keygen)
define('CRYPT_RSA_PUBLIC_FORMAT_PKCS8', 7);
* Pure-PHP PKCS#1 compliant implementation of RSA.
* @author Jim Wigginton <terrafrost@php.net>
public $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
public $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS8;
* Primes for Chinese Remainder Theorem (ie. p and q)
* Exponents for Chinese Remainder Theorem (ie. dP and dQ)
* Coefficients for Chinese Remainder Theorem (ie. qInv)
* Length of hash function output
* Hash function for the Mask Generation Function
* Length of MGF hash function output
public $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
public $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
public $publicExponent = false;
public $password = false;
* For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
* because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
* @see Crypt_RSA::_start_element_handler()
public $components = array();
* For use with parsing XML formatted keys.
* @see Crypt_RSA::_character_handler()
* @see Crypt_RSA::_stop_element_handler()
* OpenSSL configuration file name.
* Set to null to use system configuration file.
* @see Crypt_RSA::createKey()
* Public key comment field.
public $comment = 'phpseclib-generated-key';
* If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
* Crypt_RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
* openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
public function __construct()
if (!class_exists('Math_BigInteger')) {
require_once dirname(__FILE__).'/../Math/BigInteger.php';
$this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
if (!defined('CRYPT_RSA_MODE')) {
// Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
// Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
// can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
if (defined('MATH_BIGINTEGER_OPENSSL_DISABLE')) {
define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);