/** * 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 = '') { if (count($primes) != 2) { return false; } $raw = array('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)); $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: "; $encryption = !empty($password) || is_string($password) ? 'aes256-cbc' : 'none'; $key .= $encryption; $key .= "\r\nComment: " . self::$comment . "\r\n"; $public = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']); $source = pack('Na*Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption, strlen(self::$comment), self::$comment, strlen($public), $public); $public = Base64::encode($public); $key .= "Public-Lines: " . (strlen($public) + 63 >> 6) . "\r\n"; $key .= chunk_split($public, 64); $private = pack('Na*Na*Na*Na*', strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'], strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']); if (empty($password) && !is_string($password)) { $source .= pack('Na*', strlen($private), $private); $hashkey = 'putty-private-key-file-mac-key'; } else { $private .= Random::string(16 - (strlen($private) & 15)); $source .= pack('Na*', strlen($private), $private); $crypto = new AES(); $crypto->setKey(static::generateSymmetricKey($password, 32)); $crypto->setIV(str_repeat("", $crypto->getBlockLength() >> 3)); $crypto->disablePadding(); $private = $crypto->encrypt($private); $hashkey = 'putty-private-key-file-mac-key' . $password; } $private = Base64::encode($private); $key .= 'Private-Lines: ' . (strlen($private) + 63 >> 6) . "\r\n"; $key .= chunk_split($private, 64); $hash = new Hash('sha1'); $hash->setKey(sha1($hashkey, true)); $key .= 'Private-MAC: ' . Hex::encode($hash->hash($source)) . "\r\n"; return $key; }