我不熟悉 RSA 证书,所以我不确定我缺少什么来完成我所需要的。
我们需要发送的文件的收件人在 .txt 文件中向我们提供了这样的密钥(简而言之):
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAnONJwckqYNzkJPUQ/yRRFgbf2MGkJxcEXTt3B2qw5a+FK2De
dNf7BDHUuLJZLGab4Cp9iWJu0pwWv66pui3a/J5EnR8jGy8IwnCB4Q==
-----END RSA PRIVATE KEY-----
我将其保存在我们的系统中,名称为 cert.pem,权限为 0600。
现在我们需要验证他们的服务器才能通过 SFTP 发送文件。根据文档,这就是我们得到的:
$conn = phpseclib3\Net\SFTP($host);
$privateKeyContent = file_get_contents('path/to/cert.pem');
$privateKey = \phpseclib3\Crypt\PublicKeyLoader::load($privateKeyContent);
$conn->login($username, $privateKey);
但是,当进程进入
PublicKeyLoader::load()
时,我收到此异常: 无法解码 JSON,从 \phpseclib3\Crypt\Common\Formats\Keys\JWK::load()
抛出,因为它需要 JSON 可解析字符串而不是“原始”pem 内容。
如果我将“原始”私钥内容发送到
phpseclib3\Net\SFTP::login()
,我会收到密码错误消息
我还需要采取哪些额外步骤才能使其正常工作?
这并不是一个真正的答案,但它太长了,无法作为评论发布。
无论如何,这个错误没有任何意义。
所以在Crypt/Common/Formats/Keys/JWK.php中有这样的:
if (PHP_VERSION_ID >= 73000) {
$key = json_decode($key, null, 512, JSON_THROW_ON_ERROR);
} else {
$key = json_decode($key);
if (!$key) {
throw new \RuntimeException('Unable to decode JSON');
}
}
所以异常肯定会被抛出,但它也被捕获了。您的堆栈跟踪提到 phpseclib\Crypt\Common\AmetryKey::load。该方法捕获所有\异常:
foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) {
if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) {
continue;
}
try {
$components = $format::load($key, $password);
} catch (\Exception $e) {
$components = false;
}
if ($components !== false) {
break;
}
}
if ($components === false) {
throw new NoKeyLoadedException('Unable to read key');
}
它正在执行一个 for 循环,尝试每个存在的插件,如果没有一个真正加载该插件,则抛出 NoKeyLoadedException 。但你没有得到
NoKeyLoadedException('Unable to read key')
- 你似乎得到了 \RuntimeException('Unable to decode JSON')
异常。
那么
phpseclib\Crypt\Common\AsymmetricKey::load
为何没有捕获 JWK 异常呢?我不知道。
我的意思是,我想如果一个自定义修改 PHP 以非标准方式运行或修改 phpseclib 以非标准方式运行,那么人们可以实现你所实现的结果,但如果你做了其中任何一件事,那么你的帖子应该提到...