Exemplo n.º 1
0
 /**
  * Generates a random BigInteger
  *
  * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
  *
  * @param int $length
  * @return \phpseclib\Math\BigInteger
  * @access private
  */
 function _random_number_helper($size)
 {
     if (class_exists('\\phpseclib\\Crypt\\Random')) {
         $random = Random::string($size);
     } else {
         $random = '';
         if ($size & 1) {
             $random .= chr(mt_rand(0, 255));
         }
         $blocks = $size >> 1;
         for ($i = 0; $i < $blocks; ++$i) {
             // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
             $random .= pack('n', mt_rand(0, 0xffff));
         }
     }
     return new static($random, 256);
 }
Exemplo n.º 2
0
 /**
  * RSA Encrypt
  *
  * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e
  * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1.  Could just make anything that
  * calls this call modexp, instead, but I think this makes things clearer, maybe...
  *
  * @see self::__construct()
  * @param BigInteger $m
  * @param array $key
  * @return BigInteger
  * @access private
  */
 function _rsa_crypt($m, $key)
 {
     /*
     $rsa = new RSA();
     $rsa->load($key, 'raw');
     $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
     return $rsa->encrypt($m);
     */
     // To quote from protocol-1.5.txt:
     // The most significant byte (which is only partial as the value must be
     // less than the public modulus, which is never a power of two) is zero.
     //
     // The next byte contains the value 2 (which stands for public-key
     // encrypted data in the PKCS standard [PKCS#1]).  Then, there are non-
     // zero random bytes to fill any unused space, a zero byte, and the data
     // to be encrypted in the least significant bytes, the last byte of the
     // data in the least significant byte.
     // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation",
     // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL:
     // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
     $modulus = $key[1]->toBytes();
     $length = strlen($modulus) - strlen($m) - 3;
     $random = '';
     while (strlen($random) != $length) {
         $block = Random::string($length - strlen($random));
         $block = str_replace("", '', $block);
         $random .= $block;
     }
     $temp = chr(0) . chr(2) . $random . chr(0) . $m;
     $m = new BigInteger($temp, 256);
     $m = $m->modPow($key[0], $key[1]);
     return $m->toBytes();
 }
Exemplo n.º 3
0
 /**
  * Convert a private key to the appropriate format.
  *
  * @access public
  * @param \phpseclib\Math\BigInteger $n
  * @param \phpseclib\Math\BigInteger $e
  * @param \phpseclib\Math\BigInteger $d
  * @param array $primes
  * @param array $exponents
  * @param array $coefficients
  * @param string $password optional
  * @return string
  */
 static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, $primes, $exponents, $coefficients, $password = '')
 {
     $num_primes = count($primes);
     $raw = array('version' => $num_primes == 2 ? chr(0) : chr(1), 'modulus' => $n->toBytes(true), 'publicExponent' => $e->toBytes(true), 'privateExponent' => $d->toBytes(true), 'prime1' => $primes[1]->toBytes(true), 'prime2' => $primes[2]->toBytes(true), 'exponent1' => $exponents[1]->toBytes(true), 'exponent2' => $exponents[2]->toBytes(true), 'coefficient' => $coefficients[2]->toBytes(true));
     $components = array();
     foreach ($raw as $name => $value) {
         $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($value)), $value);
     }
     $RSAPrivateKey = implode('', $components);
     if ($num_primes > 2) {
         $OtherPrimeInfos = '';
         for ($i = 3; $i <= $num_primes; $i++) {
             // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
             //
             // OtherPrimeInfo ::= SEQUENCE {
             //     prime             INTEGER,  -- ri
             //     exponent          INTEGER,  -- di
             //     coefficient       INTEGER   -- ti
             // }
             $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
             $OtherPrimeInfo .= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
             $OtherPrimeInfo .= pack('Ca*a*', self::ASN1_INTEGER, self::_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
             $OtherPrimeInfos .= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
         }
         $RSAPrivateKey .= pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
     }
     $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, self::_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
     if (!empty($password) || is_string($password)) {
         $cipher = self::getEncryptionObject(self::$defaultEncryptionAlgorithm);
         $iv = Random::string($cipher->getBlockLength() >> 3);
         $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength()));
         $cipher->setIV($iv);
         $iv = strtoupper(bin2hex($iv));
         $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: " . self::$defaultEncryptionAlgorithm . ",{$iv}\r\n" . "\r\n" . chunk_split(base64_encode($cipher->encrypt($RSAPrivateKey)), 64) . '-----END RSA PRIVATE KEY-----';
     } else {
         $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" . chunk_split(base64_encode($RSAPrivateKey), 64) . '-----END RSA PRIVATE KEY-----';
     }
     return $RSAPrivateKey;
 }
Exemplo n.º 4
0
 /**
  * Sends Binary Packets
  *
  * See '6. Binary Packet Protocol' of rfc4253 for more info.
  *
  * @param string $data
  * @param string $logged
  * @see self::_get_binary_packet()
  * @return bool
  * @access private
  */
 function _send_binary_packet($data, $logged = null)
 {
     if (!is_resource($this->fsock) || feof($this->fsock)) {
         $this->bitmap = 0;
         throw new \RuntimeException('Connection closed prematurely');
     }
     //if ($this->compress) {
     //    // the -4 removes the checksum:
     //    // http://php.net/function.gzcompress#57710
     //    $data = substr(gzcompress($data), 0, -4);
     //}
     // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9
     $packet_length = strlen($data) + 9;
     // round up to the nearest $this->encrypt_block_size
     $packet_length += ($this->encrypt_block_size - 1) * $packet_length % $this->encrypt_block_size;
     // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length
     $padding_length = $packet_length - strlen($data) - 5;
     $padding = Random::string($padding_length);
     // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself
     $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
     $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : '';
     $this->send_seq_no++;
     if ($this->encrypt !== false) {
         $packet = $this->encrypt->encrypt($packet);
     }
     $packet .= $hmac;
     $start = microtime(true);
     $result = strlen($packet) == fputs($this->fsock, $packet);
     $stop = microtime(true);
     if (defined('NET_SSH2_LOGGING')) {
         $current = microtime(true);
         $message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')';
         $message_number = '-> ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
         $this->_append_log($message_number, isset($logged) ? $logged : $data);
         $this->last_packet = $current;
     }
     return $result;
 }