phpseclib\Net\SSH2::getServerPublicHostKey PHP Méthode

getServerPublicHostKey() public méthode

Caching this the first time you connect to a server and checking the result on subsequent connections is recommended. Returns false if the server signature is not signed correctly with the public host key.
public getServerPublicHostKey ( ) : mixed
Résultat mixed
    function getServerPublicHostKey()
    {
        if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
            if (!$this->_connect()) {
                return false;
            }
        }
        $signature = $this->signature;
        $server_public_host_key = $this->server_public_host_key;
        if (strlen($server_public_host_key) < 4) {
            return false;
        }
        extract(unpack('Nlength', Strings::shift($server_public_host_key, 4)));
        Strings::shift($server_public_host_key, $length);
        if ($this->signature_validated) {
            return $this->bitmap ? $this->signature_format . ' ' . Base64::encode($this->server_public_host_key) : false;
        }
        $this->signature_validated = true;
        switch ($this->signature_format) {
            case 'ssh-dss':
                $zero = new BigInteger();
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $p = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $q = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $g = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $y = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
                /* The value for 'dss_signature_blob' is encoded as a string containing
                   r, followed by s (which are 160-bit integers, without lengths or
                   padding, unsigned, and in network byte order). */
                $temp = unpack('Nlength', Strings::shift($signature, 4));
                if ($temp['length'] != 40) {
                    $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                    throw new \RuntimeException('Invalid signature');
                }
                $r = new BigInteger(Strings::shift($signature, 20), 256);
                $s = new BigInteger(Strings::shift($signature, 20), 256);
                switch (true) {
                    case $r->equals($zero):
                    case $r->compare($q) >= 0:
                    case $s->equals($zero):
                    case $s->compare($q) >= 0:
                        $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                        throw new \RuntimeException('Invalid signature');
                }
                $w = $s->modInverse($q);
                $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16));
                list(, $u1) = $u1->divide($q);
                $u2 = $w->multiply($r);
                list(, $u2) = $u2->divide($q);
                $g = $g->modPow($u1, $p);
                $y = $y->modPow($u2, $p);
                $v = $g->multiply($y);
                list(, $v) = $v->divide($p);
                list(, $v) = $v->divide($q);
                if (!$v->equals($r)) {
                    //user_error('Bad server signature');
                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
                }
                break;
            case 'ssh-rsa':
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $e = new BigInteger(Strings::shift($server_public_host_key, $temp['length']), -256);
                if (strlen($server_public_host_key) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($server_public_host_key, 4));
                $rawN = Strings::shift($server_public_host_key, $temp['length']);
                $n = new BigInteger($rawN, -256);
                $nLength = strlen(ltrim($rawN, ""));
                /*
                if (strlen($signature) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($signature, 4));
                $signature = Strings::shift($signature, $temp['length']);
                
                $rsa = new RSA();
                $rsa->load(array('e' => $e, 'n' => $n), 'raw');
                $rsa->setHash('sha1');
                if (!$rsa->verify($this->exchange_hash, $signature, RSA::PADDING_PKCS1)) {
                    //user_error('Bad server signature');
                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
                }
                */
                if (strlen($signature) < 4) {
                    return false;
                }
                $temp = unpack('Nlength', Strings::shift($signature, 4));
                $s = new BigInteger(Strings::shift($signature, $temp['length']), 256);
                // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the
                // following URL:
                // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
                // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
                if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
                    $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
                    throw new \RuntimeException('Invalid signature');
                }
                $s = $s->modPow($e, $n);
                $s = $s->toBytes();
                $h = pack('N4H*', 0x302130, 0x906052b, 0xe03021a, 0x5000414, sha1($this->exchange_hash));
                $h = chr(0x1) . str_repeat(chr(0xff), $nLength - 2 - strlen($h)) . $h;
                if ($s != $h) {
                    //user_error('Bad server signature');
                    return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
                }
                break;
            default:
                $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
                throw new NoSupportedAlgorithmsException('Unsupported signature format');
        }
        return $this->signature_format . ' ' . Base64::encode($this->server_public_host_key);
    }

Usage Example

 /**
  * @param string $hashingMethod "sha1" or "md5"
  * @return mixed
  */
 public function getForeignKeyFingerprint($hashingMethod)
 {
     switch ($hashingMethod) {
         case self::HASHING_SHA1:
             $hashingMethod = function ($string) {
                 return sha1($string);
             };
             break;
         case self::HASHING_MD5:
         default:
             $hashingMethod = function ($string) {
                 return md5($string);
             };
     }
     $foreignPublicKey = explode(' ', $this->ssh->getServerPublicHostKey());
     return $hashingMethod(base64_decode($foreignPublicKey[1]));
 }
All Usage Examples Of phpseclib\Net\SSH2::getServerPublicHostKey