466        $this->configFile = dirname(__FILE__) . 
'/../openssl.cnf';
 
  468        if (!defined(
'CRYPT_RSA_MODE')) {
 
  473                case defined(
'MATH_BIGINTEGER_OPENSSL_DISABLE'):
 
  474                    define(
'CRYPT_RSA_MODE', self::MODE_INTERNAL);
 
  476                case extension_loaded(
'openssl') && file_exists($this->configFile):
 
  480                    $content = ob_get_contents();
 
  483                    preg_match_all(
'#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
 
  486                    if (!empty($matches[1])) {
 
  487                        for (
$i = 0; 
$i < count($matches[1]); 
$i++) {
 
  488                            $fullVersion = trim(str_replace(
'=>', 
'', strip_tags($matches[2][
$i])));
 
  491                            if (!preg_match(
'/(\d+\.\d+\.\d+)/i', $fullVersion, 
$m)) {
 
  492                                $versions[$matches[1][
$i]] = $fullVersion;
 
  494                                $versions[$matches[1][
$i]] = 
$m[0];
 
  501                        case !isset($versions[
'Header']):
 
  502                        case !isset($versions[
'Library']):
 
  503                        case $versions[
'Header'] == $versions[
'Library']:
 
  504                            define(
'CRYPT_RSA_MODE', self::MODE_OPENSSL);
 
  507                            define(
'CRYPT_RSA_MODE', self::MODE_INTERNAL);
 
  508                            define(
'MATH_BIGINTEGER_OPENSSL_DISABLE', 
true);
 
  512                    define(
'CRYPT_RSA_MODE', self::MODE_INTERNAL);
 
  520        $this->hLen = $this->
hash->getLength();
 
  521        $this->hashName = 
'sha1';
 
  522        $this->mgfHash = 
new Hash(
'sha1');
 
  523        $this->mgfHLen = $this->mgfHash->getLength();
 
  540    function createKey($bits = 1024, $timeout = 
false, $partial = array())
 
  542        if (!defined(
'CRYPT_RSA_EXPONENT')) {
 
  544            define(
'CRYPT_RSA_EXPONENT', 
'65537');
 
  552        if (!defined(
'CRYPT_RSA_SMALLEST_PRIME')) {
 
  553            define(
'CRYPT_RSA_SMALLEST_PRIME', 4096);
 
  557        if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
 
  559            if (isset($this->configFile)) {
 
  562            $rsa = openssl_pkey_new(array(
'private_key_bits' => $bits) + 
$config);
 
  563            openssl_pkey_export($rsa, $privatekey, 
null, 
$config);
 
  564            $publickey = openssl_pkey_get_details($rsa);
 
  565            $publickey = $publickey[
'key'];
 
  567            $privatekey = call_user_func_array(array($this, 
'_convertPrivateKey'), array_values($this->
_parseKey($privatekey, self::PRIVATE_FORMAT_PKCS1)));
 
  568            $publickey = call_user_func_array(array($this, 
'_convertPublicKey'), array_values($this->
_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1)));
 
  571            while (openssl_error_string() !== 
false) {
 
  575                'privatekey' => $privatekey,
 
  576                'publickey' => $publickey,
 
  577                'partialkey' => 
false 
  589        if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
 
  590            $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
 
  591            $temp = CRYPT_RSA_SMALLEST_PRIME;
 
  601        $n = $this->one->copy();
 
  602        if (!empty($partial)) {
 
  603            extract(unserialize($partial));
 
  607                'top' => $this->one->copy(),
 
  616            for (
$i = $i0; 
$i <= $num_primes; 
$i++) {
 
  617                if ($timeout !== 
false) {
 
  618                    $timeout-= time() - 
$start;
 
  624                            'partialkey' => serialize(array(
 
  634                if (
$i == $num_primes) {
 
  635                    list($min, $temp) = $absoluteMin->divide(
$n);
 
  636                    if (!$temp->equals($this->zero)) {
 
  637                        $min = $min->add($this->one); 
 
  639                    $primes[
$i] = $generator->randomPrime($min, $finalMax, $timeout);
 
  641                    $primes[
$i] = $generator->randomPrime($min, $max, $timeout);
 
  649                        $partialkey = serialize(array(
 
  660                        'partialkey' => $partialkey
 
  672                $temp = 
$primes[
$i]->subtract($this->one);
 
  676                $lcm[
'top'] = $lcm[
'top']->multiply($temp);
 
  677                $lcm[
'bottom'] = $lcm[
'bottom'] === 
false ? $temp : $lcm[
'bottom']->gcd($temp);
 
  682            list($temp) = $lcm[
'top']->divide($lcm[
'bottom']);
 
  683            $gcd = $temp->gcd($e);
 
  685        } 
while (!$gcd->equals($this->one));
 
  687        $d = $e->modInverse($temp);
 
  708            'partialkey' => 
false 
  725            'version' => $num_primes == 2 ? chr(0) : chr(1), 
 
  726            'modulus' => 
$n->toBytes($signed),
 
  727            'publicExponent' => $e->toBytes($signed),
 
  728            'privateExponent' => 
$d->toBytes($signed),
 
  729            'prime1' => 
$primes[1]->toBytes($signed),
 
  730            'prime2' => 
$primes[2]->toBytes($signed),
 
  731            'exponent1' => 
$exponents[1]->toBytes($signed),
 
  732            'exponent2' => 
$exponents[2]->toBytes($signed),
 
  738        switch ($this->privateKeyFormat) {
 
  740                if ($num_primes != 2) {
 
  743                return "<RSAKeyValue>\r\n" .
 
  744                       '  <Modulus>' . base64_encode($raw[
'modulus']) . 
"</Modulus>\r\n" .
 
  745                       '  <Exponent>' . base64_encode($raw[
'publicExponent']) . 
"</Exponent>\r\n" .
 
  746                       '  <P>' . base64_encode($raw[
'prime1']) . 
"</P>\r\n" .
 
  747                       '  <Q>' . base64_encode($raw[
'prime2']) . 
"</Q>\r\n" .
 
  748                       '  <DP>' . base64_encode($raw[
'exponent1']) . 
"</DP>\r\n" .
 
  749                       '  <DQ>' . base64_encode($raw[
'exponent2']) . 
"</DQ>\r\n" .
 
  750                       '  <InverseQ>' . base64_encode($raw[
'coefficient']) . 
"</InverseQ>\r\n" .
 
  751                       '  <D>' . base64_encode($raw[
'privateExponent']) . 
"</D>\r\n" .
 
  755                if ($num_primes != 2) {
 
  758                $key = 
"PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
 
  759                $encryption = (!empty($this->password) || is_string($this->password)) ? 
'aes256-cbc' : 
'none';
 
  766                    strlen($raw[
'publicExponent']),
 
  767                    $raw[
'publicExponent'],
 
  768                    strlen($raw[
'modulus']),
 
  782                $public = base64_encode($public);
 
  783                $key.= 
"Public-Lines: " . ((strlen($public) + 63) >> 6) . 
"\r\n";
 
  784                $key.= chunk_split($public, 64);
 
  787                    strlen($raw[
'privateExponent']),
 
  788                    $raw[
'privateExponent'],
 
  789                    strlen($raw[
'prime1']),
 
  791                    strlen($raw[
'prime2']),
 
  793                    strlen($raw[
'coefficient']),
 
  796                if (empty($this->password) && !is_string($this->password)) {
 
  797                    $source.= pack(
'Na*', strlen($private), $private);
 
  798                    $hashkey = 
'putty-private-key-file-mac-key';
 
  801                    $source.= pack(
'Na*', strlen($private), $private);
 
  804                    while (strlen($symkey) < 32) {
 
  805                        $temp = pack(
'Na*', $sequence++, $this->password);
 
  806                        $symkey.= pack(
'H*', sha1($temp));
 
  808                    $symkey = substr($symkey, 0, 32);
 
  811                    $crypto->setKey($symkey);
 
  812                    $crypto->disablePadding();
 
  813                    $private = $crypto->encrypt($private);
 
  817                $private = base64_encode($private);
 
  818                $key.= 
'Private-Lines: ' . ((strlen($private) + 63) >> 6) . 
"\r\n";
 
  819                $key.= chunk_split($private, 64);
 
  821                $hash->setKey(pack(
'H*', sha1($hashkey)));
 
  827                foreach ($raw as 
$name => $value) {
 
  833                if ($num_primes > 2) {
 
  834                    $OtherPrimeInfos = 
'';
 
  835                    for (
$i = 3; 
$i <= $num_primes; 
$i++) {
 
  846                        $OtherPrimeInfos.= pack(
'Ca*a*', self::ASN1_SEQUENCE, $this->
_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
 
  848                    $RSAPrivateKey.= pack(
'Ca*a*', self::ASN1_SEQUENCE, $this->
_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
 
  851                $RSAPrivateKey = pack(
'Ca*a*', self::ASN1_SEQUENCE, $this->
_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
 
  853                if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
 
  854                    $rsaOID = pack(
'H*', 
'300d06092a864886f70d0101010500'); 
 
  855                    $RSAPrivateKey = pack(
 
  864                    $RSAPrivateKey = pack(
'Ca*a*', self::ASN1_SEQUENCE, $this->
_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
 
  865                    if (!empty($this->password) || is_string($this->password)) {
 
  867                        $iterationCount = 2048;
 
  870                        $crypto->setPassword($this->password, 
'pbkdf1', 
'md5', $salt, $iterationCount);
 
  871                        $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
 
  875                            self::ASN1_OCTETSTRING,
 
  882                        $pbeWithMD5AndDES_CBC = 
"\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
 
  884                        $encryptionAlgorithm = pack(
 
  888                            $pbeWithMD5AndDES_CBC,
 
  894                        $RSAPrivateKey = pack(
 
  898                            $encryptionAlgorithm,
 
  899                            self::ASN1_OCTETSTRING,
 
  904                        $RSAPrivateKey = pack(
'Ca*a*', self::ASN1_SEQUENCE, $this->
_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
 
  906                        $RSAPrivateKey = 
"-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
 
  907                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
 
  908                                         '-----END ENCRYPTED PRIVATE KEY-----';
 
  910                        $RSAPrivateKey = 
"-----BEGIN PRIVATE KEY-----\r\n" .
 
  911                                         chunk_split(base64_encode($RSAPrivateKey), 64) .
 
  912                                         '-----END PRIVATE KEY-----';
 
  914                    return $RSAPrivateKey;
 
  917                if (!empty($this->password) || is_string($this->password)) {
 
  919                    $symkey = pack(
'H*', md5($this->password . $iv)); 
 
  920                    $symkey.= substr(pack(
'H*', md5($symkey . $this->password . $iv)), 0, 8);
 
  922                    $des->setKey($symkey);
 
  924                    $iv = strtoupper(bin2hex($iv));
 
  925                    $RSAPrivateKey = 
"-----BEGIN RSA PRIVATE KEY-----\r\n" .
 
  926                                     "Proc-Type: 4,ENCRYPTED\r\n" .
 
  927                                     "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
 
  929                                     chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
 
  930                                     '-----END RSA PRIVATE KEY-----';
 
  932                    $RSAPrivateKey = 
"-----BEGIN RSA PRIVATE KEY-----\r\n" .
 
  933                                     chunk_split(base64_encode($RSAPrivateKey), 64) .
 
  934                                     '-----END RSA PRIVATE KEY-----';
 
  937                return $RSAPrivateKey;
 
  956        switch ($this->publicKeyFormat) {
 
  958                return array(
'e' => $e->copy(), 
'n' => 
$n->copy());
 
  960                return "<RSAKeyValue>\r\n" .
 
  961                       '  <Modulus>' . base64_encode(
$modulus) . 
"</Modulus>\r\n" .
 
  971                $RSAPublicKey = 
'ssh-rsa ' . base64_encode($RSAPublicKey) . 
' ' . 
$this->comment;
 
  973                return $RSAPublicKey;
 
  985                $RSAPublicKey = pack(
 
  993                if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) {
 
  994                    $RSAPublicKey = 
"-----BEGIN RSA PUBLIC KEY-----\r\n" .
 
  995                                    chunk_split(base64_encode($RSAPublicKey), 64) .
 
  996                                    '-----END RSA PUBLIC KEY-----';
 
  999                    $rsaOID = pack(
'H*', 
'300d06092a864886f70d0101010500'); 
 
 1000                    $RSAPublicKey = chr(0) . $RSAPublicKey;
 
 1001                    $RSAPublicKey = chr(3) . $this->
_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
 
 1003                    $RSAPublicKey = pack(
 
 1005                        self::ASN1_SEQUENCE,
 
 1007                        $rsaOID . $RSAPublicKey
 
 1010                    $RSAPublicKey = 
"-----BEGIN PUBLIC KEY-----\r\n" .
 
 1011                                     chunk_split(base64_encode($RSAPublicKey), 64) .
 
 1012                                     '-----END PUBLIC KEY-----';
 
 1015                return $RSAPublicKey;
 
 1031        if (
$type != self::PUBLIC_FORMAT_RAW && !is_string(
$key)) {
 
 1037                if (!is_array(
$key)) {
 
 1042                    case isset(
$key[
'e']):
 
 1045                    case isset(
$key[
'exponent']):
 
 1048                    case isset(
$key[
'publicExponent']):
 
 1051                    case isset(
$key[0]):
 
 1055                    case isset(
$key[
'n']):
 
 1058                    case isset(
$key[
'modulo']):
 
 1061                    case isset(
$key[
'modulus']):
 
 1064                    case isset(
$key[1]):
 
 1086                if (preg_match(
'#DEK-Info: (.+),(.+)#', 
$key, $matches)) {
 
 1087                    $iv = pack(
'H*', trim($matches[2]));
 
 1088                    $symkey = pack(
'H*', md5($this->password . substr($iv, 0, 8))); 
 
 1089                    $symkey.= pack(
'H*', md5($symkey . $this->password . substr($iv, 0, 8)));
 
 1091                    $key = preg_replace(
'#^(?:Proc-Type|DEK-Info): .*#m', 
'', 
$key);
 
 1093                    if ($ciphertext === 
false) {
 
 1096                    switch ($matches[1]) {
 
 1098                            $crypto = 
new AES();
 
 1101                            $symkey = substr($symkey, 0, 16);
 
 1102                            $crypto = 
new AES();
 
 1104                        case 'DES-EDE3-CFB':
 
 1107                        case 'DES-EDE3-CBC':
 
 1108                            $symkey = substr($symkey, 0, 24);
 
 1112                            $crypto = 
new DES();
 
 1117                    $crypto->setKey($symkey);
 
 1118                    $crypto->setIV($iv);
 
 1119                    $decoded = $crypto->decrypt($ciphertext);
 
 1124                if ($decoded !== 
false) {
 
 1149                if (
$tag == self::ASN1_INTEGER && substr(
$key, 0, 3) == 
"\x01\x00\x30") {
 
 1154                if (
$tag == self::ASN1_SEQUENCE) {
 
 1156                    if (ord($this->
_string_shift($temp)) != self::ASN1_OBJECT) {
 
 1161                        case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": 
 
 1163                        case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": 
 
 1169                            if (ord($this->
_string_shift($temp)) != self::ASN1_SEQUENCE) {
 
 1177                            if (ord($this->
_string_shift($temp)) != self::ASN1_INTEGER) {
 
 1181                            list(, $iterationCount) = unpack(
'N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
 
 1184                            if (strlen(
$key) != $length) {
 
 1188                            $crypto = 
new DES();
 
 1189                            $crypto->setPassword($this->password, 
'pbkdf1', 
'md5', $salt, $iterationCount);
 
 1191                            if (
$key === 
false) {
 
 1210                    if (
$tag == self::ASN1_BITSTRING) {
 
 1221                if (
$tag != self::ASN1_INTEGER) {
 
 1227                if (strlen($temp) != 1 || ord($temp) > 2) {
 
 1267                    while (!empty(
$key)) {
 
 1286                $parts = explode(
' ', 
$key, 3);
 
 1288                $key = isset($parts[1]) ? base64_decode($parts[1]) : 
false;
 
 1289                if (
$key === 
false) {
 
 1293                $comment = isset($parts[2]) ? $parts[2] : 
false;
 
 1295                $cleanup = substr(
$key, 0, 11) == 
"\0\0\0\7ssh-rsa";
 
 1297                if (strlen(
$key) <= 4) {
 
 1302                if (strlen(
$key) <= 4) {
 
 1308                if ($cleanup && strlen(
$key)) {
 
 1309                    if (strlen(
$key) <= 4) {
 
 1314                    return strlen(
$key) ? false : array(
 
 1315                        'modulus' => $realModulus,
 
 1320                    return strlen(
$key) ? false : array(
 
 1330                $this->components = array();
 
 1332                $xml = xml_parser_create(
'UTF-8');
 
 1333                xml_set_object(
$xml, $this);
 
 1334                xml_set_element_handler(
$xml, 
'_start_element_handler', 
'_stop_element_handler');
 
 1335                xml_set_character_data_handler(
$xml, 
'_data_handler');
 
 1337                if (!xml_parse(
$xml, 
'<xml>' . 
$key . 
'</xml>')) {
 
 1341                return isset($this->components[
'modulus']) && isset($this->components[
'publicExponent']) ? $this->components : 
false;
 
 1345                $key = preg_split(
'#\r\n|\r|\n#', 
$key);
 
 1346                $type = trim(preg_replace(
'#PuTTY-User-Key-File-2: (.+)#', 
'$1', 
$key[0]));
 
 1347                if (
$type != 
'ssh-rsa') {
 
 1350                $encryption = trim(preg_replace(
'#Encryption: (.+)#', 
'$1', 
$key[1]));
 
 1351                $comment = trim(preg_replace(
'#Comment: (.+)#', 
'$1', 
$key[2]));
 
 1353                $publicLength = trim(preg_replace(
'#Public-Lines: (\d+)#', 
'$1', 
$key[3]));
 
 1354                $public = base64_decode(implode(
'', array_map(
'trim', array_slice(
$key, 4, $publicLength))));
 
 1355                $public = substr($public, 11);
 
 1356                extract(unpack(
'Nlength', $this->
_string_shift($public, 4)));
 
 1358                extract(unpack(
'Nlength', $this->
_string_shift($public, 4)));
 
 1361                $privateLength = trim(preg_replace(
'#Private-Lines: (\d+)#', 
'$1', 
$key[$publicLength + 4]));
 
 1362                $private = base64_decode(implode(
'', array_map(
'trim', array_slice(
$key, $publicLength + 5, $privateLength))));
 
 1364                switch ($encryption) {
 
 1368                        while (strlen($symkey) < 32) {
 
 1369                            $temp = pack(
'Na*', $sequence++, $this->password);
 
 1370                            $symkey.= pack(
'H*', sha1($temp));
 
 1372                        $symkey = substr($symkey, 0, 32);
 
 1373                        $crypto = 
new AES();
 
 1376                if ($encryption != 
'none') {
 
 1377                    $crypto->setKey($symkey);
 
 1378                    $crypto->disablePadding();
 
 1379                    $private = $crypto->decrypt($private);
 
 1380                    if ($private === 
false) {
 
 1385                extract(unpack(
'Nlength', $this->
_string_shift($private, 4)));
 
 1386                if (strlen($private) < $length) {
 
 1390                extract(unpack(
'Nlength', $this->
_string_shift($private, 4)));
 
 1391                if (strlen($private) < $length) {
 
 1395                extract(unpack(
'Nlength', $this->
_string_shift($private, 4)));
 
 1396                if (strlen($private) < $length) {
 
 1401                $temp = 
$components[
'primes'][1]->subtract($this->one);
 
 1403                $temp = 
$components[
'primes'][2]->subtract($this->one);
 
 1406                extract(unpack(
'Nlength', $this->
_string_shift($private, 4)));
 
 1407                if (strlen($private) < $length) {
 
 1426        return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits());
 
 1444                $this->current = &$this->components[
'modulus'];
 
 1447                $this->current = &$this->components[
'publicExponent'];
 
 1450                $this->current = &$this->components[
'primes'][1];
 
 1453                $this->current = &$this->components[
'primes'][2];
 
 1456                $this->current = &$this->components[
'exponents'][1];
 
 1459                $this->current = &$this->components[
'exponents'][2];
 
 1462                $this->current = &$this->components[
'coefficients'][2];
 
 1465                $this->current = &$this->components[
'privateExponent'];
 
 1467        $this->current = 
'';
 
 1481        if (isset($this->current)) {
 
 1482            $this->current = 
new BigInteger(base64_decode($this->current), 256);
 
 1483            unset($this->current);
 
 1498        if (!isset($this->current) || is_object($this->current)) {
 
 1501        $this->current.= trim(
$data);
 
 1516            $this->privateKeyFormat = 
$key->privateKeyFormat;
 
 1517            $this->publicKeyFormat = 
$key->publicKeyFormat;
 
 1519            $this->hLen = 
$key->hLen;
 
 1520            $this->sLen = 
$key->sLen;
 
 1521            $this->mgfHLen = 
$key->mgfHLen;
 
 1522            $this->encryptionMode = 
$key->encryptionMode;
 
 1523            $this->signatureMode = 
$key->signatureMode;
 
 1524            $this->password = 
$key->password;
 
 1525            $this->configFile = 
$key->configFile;
 
 1528            if (is_object(
$key->hash)) {
 
 1531            if (is_object(
$key->mgfHash)) {
 
 1532                $this->mgfHash = 
new Hash(
$key->mgfHash->getHash());
 
 1535            if (is_object(
$key->modulus)) {
 
 1536                $this->modulus = 
$key->modulus->copy();
 
 1538            if (is_object(
$key->exponent)) {
 
 1539                $this->exponent = 
$key->exponent->copy();
 
 1541            if (is_object(
$key->publicExponent)) {
 
 1542                $this->publicExponent = 
$key->publicExponent->copy();
 
 1545            $this->primes = array();
 
 1546            $this->exponents = array();
 
 1547            $this->coefficients = array();
 
 1549            foreach ($this->primes as $prime) {
 
 1550                $this->primes[] = $prime->copy();
 
 1552            foreach ($this->exponents as 
$exponent) {
 
 1555            foreach ($this->coefficients as $coefficient) {
 
 1556                $this->coefficients[] = $coefficient->copy();
 
 1562        if (
$type === 
false) {
 
 1564                self::PUBLIC_FORMAT_RAW,
 
 1565                self::PRIVATE_FORMAT_PKCS1,
 
 1566                self::PRIVATE_FORMAT_XML,
 
 1567                self::PRIVATE_FORMAT_PUTTY,
 
 1568                self::PUBLIC_FORMAT_OPENSSH
 
 1570            foreach ($types as 
$type) {
 
 1580        if ($components === 
false) {
 
 1585            $this->
comment = $components[
'comment'];
 
 1588        $this->k = strlen($this->modulus->toBytes());
 
 1593            $this->coefficients = 
$components[
'coefficients'];
 
 1594            $this->publicExponent = 
$components[
'publicExponent'];
 
 1596            $this->primes = array();
 
 1597            $this->exponents = array();
 
 1598            $this->coefficients = array();
 
 1599            $this->publicExponent = 
false;
 
 1609                    case strpos(
$key, 
'-BEGIN PUBLIC KEY-') !== 
false:
 
 1610                    case strpos(
$key, 
'-BEGIN RSA PUBLIC KEY-') !== 
false:
 
 1658        if (!empty($this->publicExponent)) {
 
 1662        if (
$key === 
false && !empty($this->modulus)) {
 
 1667        if (
$type === 
false) {
 
 1669                self::PUBLIC_FORMAT_RAW,
 
 1670                self::PUBLIC_FORMAT_PKCS1,
 
 1671                self::PUBLIC_FORMAT_XML,
 
 1672                self::PUBLIC_FORMAT_OPENSSH
 
 1674            foreach ($types as 
$type) {
 
 1684        if ($components === 
false) {
 
 1688        if (empty($this->modulus) || !$this->modulus->equals(
$components[
'modulus'])) {
 
 1690            $this->exponent = $this->publicExponent = 
$components[
'publicExponent'];
 
 1694        $this->publicExponent = 
$components[
'publicExponent'];
 
 1717        if (
$key === 
false && !empty($this->publicExponent)) {
 
 1718            unset($this->publicExponent);
 
 1726        unset($rsa->publicExponent);
 
 1747        if (empty($this->modulus) || empty($this->publicExponent)) {
 
 1752        $this->publicKeyFormat = 
$type;
 
 1754        $this->publicKeyFormat = $oldFormat;
 
 1772        if (empty($this->modulus) || empty($this->publicExponent)) {
 
 1776        $modulus = $this->modulus->toBytes(
true);
 
 1781        switch ($algorithm) {
 
 1784                $base = base64_encode(
$hash->hash($RSAPublicKey));
 
 1787                return substr(chunk_split(md5($RSAPublicKey), 2, 
':'), 0, -1);
 
 1806        if (empty($this->primes)) {
 
 1811        $this->privateKeyFormat = 
$type;
 
 1812        $temp = $this->
_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients);
 
 1813        $this->privateKeyFormat = $oldFormat;
 
 1830        if (empty($this->modulus) || empty($this->exponent)) {
 
 1835        $this->publicKeyFormat = $mode;
 
 1837        $this->publicKeyFormat = $oldFormat;
 
 1850        if (
$key !== 
false) {
 
 1866        $key->loadKey($this);
 
 1879        $bytes = $bits >> 3;
 
 1880        $min = str_repeat(chr(0), $bytes);
 
 1881        $max = str_repeat(chr(0xFF), $bytes);
 
 1884            $min = chr(1 << ($msb - 1)) . $min;
 
 1885            $max = chr((1 << $msb) - 1) . $max;
 
 1887            $min[0] = chr(0x80);
 
 1909        if ($length & 0x80) { 
 
 1912            list(, $length) = unpack(
'N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
 
 1929        if ($length <= 0x7F) {
 
 1930            return chr($length);
 
 1933        $temp = ltrim(pack(
'N', $length), chr(0));
 
 1934        return pack(
'Ca*', 0x80 | strlen($temp), $temp);
 
 1949        $substr = substr($string, 0, 
$index);
 
 1950        $string = substr($string, 
$index);
 
 1963        $this->privateKeyFormat = 
$format;
 
 1975        $this->publicKeyFormat = 
$format;
 
 1998                $this->hashName = 
$hash;
 
 2002                $this->hashName = 
'sha1';
 
 2004        $this->hLen = $this->
hash->getLength();
 
 2029                $this->mgfHash = 
new Hash(
'sha1');
 
 2031        $this->mgfHLen = $this->mgfHash->getLength();
 
 2047        $this->sLen = 
$sLen;
 
 2063        if (strlen(
$x) > $xLen) {
 
 2064            user_error(
'Integer too large');
 
 2067        return str_pad(
$x, $xLen, chr(0), STR_PAD_LEFT);
 
 2095        if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
 
 2096            return $x->modPow($this->exponent, $this->modulus);
 
 2099        $num_primes = count($this->primes);
 
 2101        if (defined(
'CRYPT_RSA_DISABLE_BLINDING')) {
 
 2103                1 => 
$x->modPow($this->exponents[1], $this->primes[1]),
 
 2104                2 => 
$x->modPow($this->exponents[2], $this->primes[2])
 
 2106            $h = $m_i[1]->subtract($m_i[2]);
 
 2107            $h = 
$h->multiply($this->coefficients[2]);
 
 2108            list(, 
$h) = 
$h->divide($this->primes[1]);
 
 2109            $m = $m_i[2]->add(
$h->multiply($this->primes[2]));
 
 2111            $r = $this->primes[1];
 
 2112            for (
$i = 3; 
$i <= $num_primes; 
$i++) {
 
 2113                $m_i = 
$x->modPow($this->exponents[
$i], $this->primes[
$i]);
 
 2115                $r = 
$r->multiply($this->primes[
$i - 1]);
 
 2117                $h = $m_i->subtract(
$m);
 
 2118                $h = 
$h->multiply($this->coefficients[
$i]);
 
 2119                list(, 
$h) = 
$h->divide($this->primes[
$i]);
 
 2124            $smallest = $this->primes[1];
 
 2125            for (
$i = 2; 
$i <= $num_primes; 
$i++) {
 
 2126                if ($smallest->compare($this->primes[
$i]) > 0) {
 
 2127                    $smallest = $this->primes[
$i];
 
 2139            $h = $m_i[1]->subtract($m_i[2]);
 
 2140            $h = 
$h->multiply($this->coefficients[2]);
 
 2141            list(, 
$h) = 
$h->divide($this->primes[1]);
 
 2142            $m = $m_i[2]->add(
$h->multiply($this->primes[2]));
 
 2144            $r = $this->primes[1];
 
 2145            for (
$i = 3; 
$i <= $num_primes; 
$i++) {
 
 2148                $r = 
$r->multiply($this->primes[
$i - 1]);
 
 2150                $h = $m_i->subtract(
$m);
 
 2151                $h = 
$h->multiply($this->coefficients[
$i]);
 
 2152                list(, 
$h) = 
$h->divide($this->primes[
$i]);
 
 2175        $x = 
$x->multiply(
$r->modPow($this->publicExponent, $this->primes[
$i]));
 
 2176        $x = 
$x->modPow($this->exponents[
$i], $this->primes[
$i]);
 
 2178        $r = 
$r->modInverse($this->primes[
$i]);
 
 2180        list(, 
$x) = 
$x->divide($this->primes[
$i]);
 
 2201        if (strlen(
$x) != strlen(
$y)) {
 
 2206        for (
$i = 0; 
$i < strlen(
$x); 
$i++) {
 
 2224        if (
$m->compare($this->zero) < 0 || 
$m->compare($this->modulus) > 0) {
 
 2225            user_error(
'Message representative out of range');
 
 2242        if (
$c->compare($this->zero) < 0 || 
$c->compare($this->modulus) > 0) {
 
 2243            user_error(
'Ciphertext representative out of range');
 
 2260        if (
$m->compare($this->zero) < 0 || 
$m->compare($this->modulus) > 0) {
 
 2261            user_error(
'Message representative out of range');
 
 2278        if (
$s->compare($this->zero) < 0 || 
$s->compare($this->modulus) > 0) {
 
 2279            user_error(
'Signature representative out of range');
 
 2300        $count = ceil($maskLen / $this->mgfHLen);
 
 2301        for (
$i = 0; 
$i < $count; 
$i++) {
 
 2303            $t.= $this->mgfHash->hash($mgfSeed . 
$c);
 
 2306        return substr(
$t, 0, $maskLen);
 
 2329        if ($mLen > $this->k - 2 * $this->hLen - 2) {
 
 2330            user_error(
'Message too long');
 
 2336        $lHash = $this->
hash->hash(
$l);
 
 2337        $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
 
 2338        $db = $lHash . $ps . chr(1) . 
$m;
 
 2340        $dbMask = $this->
_mgf1($seed, $this->k - $this->hLen - 1);
 
 2341        $maskedDB = $db ^ $dbMask;
 
 2342        $seedMask = $this->
_mgf1($maskedDB, $this->hLen);
 
 2343        $maskedSeed = $seed ^ $seedMask;
 
 2344        $em = chr(0) . $maskedSeed . $maskedDB;
 
 2390        if (strlen(
$c) != $this->k || $this->k < 2 * $this->hLen + 2) {
 
 2391            user_error(
'Decryption error');
 
 2400            user_error(
'Decryption error');
 
 2407        $lHash = $this->
hash->hash(
$l);
 
 2409        $maskedSeed = substr($em, 1, $this->hLen);
 
 2410        $maskedDB = substr($em, $this->hLen + 1);
 
 2411        $seedMask = $this->
_mgf1($maskedDB, $this->hLen);
 
 2412        $seed = $maskedSeed ^ $seedMask;
 
 2413        $dbMask = $this->
_mgf1($seed, $this->k - $this->hLen - 1);
 
 2414        $db = $maskedDB ^ $dbMask;
 
 2415        $lHash2 = substr($db, 0, $this->hLen);
 
 2416        $m = substr($db, $this->hLen);
 
 2417        if ($lHash != $lHash2) {
 
 2418            user_error(
'Decryption error');
 
 2421        $m = ltrim(
$m, chr(0));
 
 2422        if (ord(
$m[0]) != 1) {
 
 2423            user_error(
'Decryption error');
 
 2429        return substr(
$m, 1);
 
 2444        $temp = $this->
_rsaep($temp);
 
 2445        return  $this->
_i2osp($temp, $this->k);
 
 2463        if ($mLen > $this->k - 11) {
 
 2464            user_error(
'Message too long');
 
 2470        $psLen = $this->k - $mLen - 3;
 
 2472        while (strlen($ps) != $psLen) {
 
 2474            $temp = str_replace(
"\x00", 
'', $temp);
 
 2479        if (defined(
'CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
 
 2482            $ps = str_repeat(
"\xFF", $psLen);
 
 2484        $em = chr(0) . chr(
$type) . $ps . chr(0) . 
$m;
 
 2520        if (strlen(
$c) != $this->k) { 
 
 2521            user_error(
'Decryption error');
 
 2531            user_error(
'Decryption error');
 
 2538        if (ord($em[0]) != 0 || ord($em[1]) > 2) {
 
 2539            user_error(
'Decryption error');
 
 2543        $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
 
 2544        $m = substr($em, strlen($ps) + 3);
 
 2546        if (strlen($ps) < 8) {
 
 2547            user_error(
'Decryption error');
 
 2570        $emLen = ($emBits + 1) >> 3; 
 
 2573        $mHash = $this->
hash->hash(
$m);
 
 2574        if ($emLen < $this->hLen + 
$sLen + 2) {
 
 2575            user_error(
'Encoding error');
 
 2580        $m2 = 
"\0\0\0\0\0\0\0\0" . $mHash . $salt;
 
 2581        $h = $this->
hash->hash($m2);
 
 2582        $ps = str_repeat(chr(0), $emLen - 
$sLen - $this->hLen - 2);
 
 2583        $db = $ps . chr(1) . $salt;
 
 2584        $dbMask = $this->
_mgf1(
$h, $emLen - $this->hLen - 1);
 
 2585        $maskedDB = $db ^ $dbMask;
 
 2586        $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
 
 2587        $em = $maskedDB . 
$h . chr(0xBC);
 
 2608        $emLen = ($emBits + 1) >> 3; 
 
 2611        $mHash = $this->
hash->hash(
$m);
 
 2612        if ($emLen < $this->hLen + 
$sLen + 2) {
 
 2616        if ($em[strlen($em) - 1] != chr(0xBC)) {
 
 2620        $maskedDB = substr($em, 0, -$this->hLen - 1);
 
 2621        $h = substr($em, -$this->hLen - 1, $this->hLen);
 
 2622        $temp = chr(0xFF << ($emBits & 7));
 
 2623        if ((~$maskedDB[0] & $temp) != $temp) {
 
 2626        $dbMask = $this->
_mgf1(
$h, $emLen - $this->hLen - 1);
 
 2627        $db = $maskedDB ^ $dbMask;
 
 2628        $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
 
 2629        $temp = $emLen - $this->hLen - 
$sLen - 2;
 
 2630        if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
 
 2633        $salt = substr($db, $temp + 1); 
 
 2634        $m2 = 
"\0\0\0\0\0\0\0\0" . $mHash . $salt;
 
 2635        $h2 = $this->
hash->hash($m2);
 
 2679        if (strlen(
$s) != $this->k) {
 
 2680            user_error(
'Invalid signature');
 
 2690        if ($m2 === 
false) {
 
 2691            user_error(
'Invalid signature');
 
 2694        $em = $this->
_i2osp($m2, $modBits >> 3);
 
 2695        if ($em === 
false) {
 
 2696            user_error(
'Invalid signature');
 
 2723        switch ($this->hashName) {
 
 2725                $t = pack(
'H*', 
'3020300c06082a864886f70d020205000410');
 
 2728                $t = pack(
'H*', 
'3020300c06082a864886f70d020505000410');
 
 2731                $t = pack(
'H*', 
'3021300906052b0e03021a05000414');
 
 2734                $t = pack(
'H*', 
'3031300d060960864801650304020105000420');
 
 2737                $t = pack(
'H*', 
'3041300d060960864801650304020205000430');
 
 2740                $t = pack(
'H*', 
'3051300d060960864801650304020305000440');
 
 2745        if ($emLen < $tLen + 11) {
 
 2746            user_error(
'Intended encoded message length too short');
 
 2750        $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
 
 2752        $em = 
"\0\1$ps\0$t";
 
 2771        if ($em === 
false) {
 
 2772            user_error(
'RSA modulus too short');
 
 2800        if (strlen(
$s) != $this->k) {
 
 2801            user_error(
'Invalid signature');
 
 2809        if ($m2 === 
false) {
 
 2810            user_error(
'Invalid signature');
 
 2813        $em = $this->
_i2osp($m2, $this->k);
 
 2814        if ($em === 
false) {
 
 2815            user_error(
'Invalid signature');
 
 2822        if ($em2 === 
false) {
 
 2823            user_error(
'RSA modulus too short');
 
 2828        return $this->
_equals($em, $em2);
 
 2841        $this->encryptionMode = $mode;
 
 2854        $this->signatureMode = $mode;
 
 2893        switch ($this->encryptionMode) {
 
 2895                $plaintext = str_split($plaintext, $this->k);
 
 2897                foreach ($plaintext as 
$m) {
 
 2902                $length = $this->k - 11;
 
 2907                $plaintext = str_split($plaintext, $length);
 
 2909                foreach ($plaintext as 
$m) {
 
 2915                $length = $this->k - 2 * $this->hLen - 2;
 
 2920                $plaintext = str_split($plaintext, $length);
 
 2922                foreach ($plaintext as 
$m) {
 
 2939        if ($this->k <= 0) {
 
 2943        $ciphertext = str_split($ciphertext, $this->k);
 
 2944        $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
 
 2948        switch ($this->encryptionMode) {
 
 2950                $decrypt = 
'_raw_encrypt';
 
 2953                $decrypt = 
'_rsaes_pkcs1_v1_5_decrypt';
 
 2957                $decrypt = 
'_rsaes_oaep_decrypt';
 
 2960        foreach ($ciphertext as 
$c) {
 
 2961            $temp = $this->$decrypt(
$c);
 
 2962            if ($temp === 
false) {
 
 2981        if (empty($this->modulus) || empty($this->exponent)) {
 
 2985        switch ($this->signatureMode) {
 
 3005        if (empty($this->modulus) || empty($this->exponent)) {
 
 3009        switch ($this->signatureMode) {
 
 3036        $temp = preg_replace(
'#.*?^-+[^-]+-+[\r\n ]*$#ms', 
'', $str, 1);
 
 3038        $temp = preg_replace(
'#-+[^-]+-+#', 
'', $temp);
 
 3040        $temp = str_replace(array(
"\r", 
"\n", 
' '), 
'', $temp);
 
 3041        $temp = preg_match(
'#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : 
false;
 
 3042        return $temp != 
false ? $temp : $str;
 
An exception for terminatinating execution or to throw for unit testing.
const MODE_CFB
Encrypt / decrypt using the Cipher Feedback mode.
_encodeLength($length)
DER-encode the length.
_exponentiate($x)
Exponentiate with or without Chinese Remainder Theorem.
_convertPublicKey($n, $e)
Convert a public key to the appropriate format.
_data_handler($parser, $data)
Data Handler.
__toString()
__toString() magic method
setPublicKeyFormat($format)
Determines the public key format.
_emsa_pss_verify($m, $em, $emBits)
EMSA-PSS-VERIFY.
setMGFHash($hash)
Determines which hashing function should be used for the mask generation function.
getSize()
Returns the key size.
_generateMinMax($bits)
Generates the smallest and largest numbers requiring $bits bits.
_mgf1($mgfSeed, $maskLen)
MGF1.
_rsassa_pkcs1_v1_5_sign($m)
RSASSA-PKCS1-V1_5-SIGN.
__clone()
__clone() magic method
const PRIVATE_FORMAT_XML
XML formatted private key.
getPrivateKey($type=self::PUBLIC_FORMAT_PKCS1)
Returns the private key.
_decodeLength(&$string)
DER-decode the length.
const ENCRYPTION_NONE
Do not use any padding.
const PUBLIC_FORMAT_PKCS1_RAW
_stop_element_handler($parser, $name)
Stop Element Handler.
_i2osp($x, $xLen)
Integer-to-Octet-String primitive.
setSaltLength($sLen)
Determines the salt length.
setSignatureMode($mode)
Set Signature Mode.
_rsaes_pkcs1_v1_5_decrypt($c)
RSAES-PKCS1-V1_5-DECRYPT.
loadKey($key, $type=false)
Loads a public or private key.
setPublicKey($key=false, $type=false)
Defines the public key.
_parseKey($key, $type)
Break a public or private key down into its constituant components.
const ENCRYPTION_PKCS1
Use PKCS#1 padding.
_blind($x, $r, $i)
Performs RSA Blinding.
_rsassa_pss_verify($m, $s)
RSASSA-PSS-VERIFY.
_os2ip($x)
Octet-String-to-Integer primitive.
const ASN1_OCTETSTRING
ASN1 Octet String.
verify($message, $signature)
Verifies a signature.
const ASN1_BITSTRING
ASN1 Bit String.
getComment()
Get public key comment.
setEncryptionMode($mode)
Set Encryption Mode.
_raw_encrypt($m)
Raw Encryption / Decryption.
const PRIVATE_FORMAT_PUTTY
PuTTY formatted private key.
getPublicKey($type=self::PUBLIC_FORMAT_PKCS8)
Returns the public key.
__construct()
The constructor.
const MODE_OPENSSL
To use the OpenSSL library.
_start_element_handler($parser, $name, $attribs)
Start Element Handler.
const PUBLIC_FORMAT_PKCS1
PKCS#1 formatted public key (raw)
_emsa_pss_encode($m, $emBits)
EMSA-PSS-ENCODE.
_extractBER($str)
Extract raw BER from Base64 encoding.
_rsassa_pkcs1_v1_5_verify($m, $s)
RSASSA-PKCS1-V1_5-VERIFY.
const ASN1_SEQUENCE
ASN1 Sequence (with the constucted bit set)
sign($message)
Create a signature.
const PUBLIC_FORMAT_RAW
#-
const PUBLIC_FORMAT_PKCS8
PKCS#1 formatted public key (encapsulated)
_rsaes_oaep_encrypt($m, $l='')
RSAES-OAEP-ENCRYPT.
_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
Convert a private key to the appropriate format.
setPassword($password=false)
Sets the password.
_emsa_pkcs1_v1_5_encode($m, $emLen)
EMSA-PKCS1-V1_5-ENCODE.
encrypt($plaintext)
Encryption.
setComment($comment)
Set public key comment.
_equals($x, $y)
Performs blinded RSA equality testing.
getPublicKeyFingerprint($algorithm='md5')
Returns the public key's fingerprint.
_rsaes_pkcs1_v1_5_encrypt($m)
RSAES-PKCS1-V1_5-ENCRYPT.
const ASN1_OBJECT
ASN1 Object Identifier.
setHash($hash)
Determines which hashing function should be used.
const PRIVATE_FORMAT_PKCS8
PKCS#8 formatted private key.
_getPrivatePublicKey($mode=self::PUBLIC_FORMAT_PKCS8)
Returns a minimalistic private key.
const PRIVATE_FORMAT_PKCS1
#-
setPrivateKeyFormat($format)
Determines the private key format.
_rsaes_oaep_decrypt($c, $l='')
RSAES-OAEP-DECRYPT.
decrypt($ciphertext)
Decryption.
const SIGNATURE_PKCS1
Use the PKCS#1 scheme by default.
const ENCRYPTION_OAEP
#+ @access public
const PUBLIC_FORMAT_XML
XML formatted public key.
createKey($bits=1024, $timeout=false, $partial=array())
Create public / private key pair.
_string_shift(&$string, $index=1)
String Shift.
setPrivateKey($key=false, $type=false)
Defines the private key.
const PUBLIC_FORMAT_OPENSSH
OpenSSH formatted public key.
_rsassa_pss_sign($m)
RSASSA-PSS-SIGN.
static string($length)
Generate a random string.
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
if(function_exists( 'posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
catch(Exception $e) $message
Pure-PHP implementation of AES.
Pure-PHP arbitrary precision integer arithmetic library.
Pure-PHP implementation of DES.
hash(StreamInterface $stream, $algo, $rawOutput=false)
Calculate a hash of a Stream.
Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic...
Pure-PHP PKCS#1 compliant implementation of RSA.
Pure-PHP implementation of Triple DES.
Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic...