使用 SSH.NET 的流私钥问题

Issue with streaming private key using SSH.NET

我正在使用 Renci.SshNet 库并使用用户名和私钥让它工作。从文件或文件流中读取时,我可以让私钥正常打开,但在内存流中失败。

这个有效:

var pk = new PrivateKeyFile(@"C:\myfile.ppk");

这个有效:

var f = new FileStream(@"C:\myfile.ppk", FileMode.Open, FileAccess.Read);
var pk = new PrivateKeyFile(f);

这些失败并显示“无效的私钥”。

var s = new MemoryStream(Encoding.UTF8.GetBytes(variablename));
//No carriage returns
var s = new MemoryStream(Encoding.UTF8.GetBytes(@"-----BEGIN RSA PRIVATE KEY----- <snip>"));
//Include carriage returns
var s = new MemoryStream(Encoding.UTF8.GetBytes(@"-----BEGIN RSA PRIVATE KEY----- <snip>"));

我什至尝试了在 SO:

上找到的流位置
private Stream GenerateStreamFromString(string s)
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}

起初我以为 Renci 库有一个错误 Stream,但显然文件流有效。我计划在 azure 存储中以字符串格式托管密钥 table,但我对其他想法持开放态度。

根据您的描述,我使用 PuTTYgen and converted my key to OpenSSH format by referring to this tutorial 通过 SSH 生成了我的私钥文件。根据你提供的使用MemoryStream的代码,我这边可以正常使用,你可以参考一下:

var f = new MemoryStream(Encoding.UTF8.GetBytes(@"-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----");
var pk = new PrivateKeyFile(f, "{password}");

注意: 我假设传递给 Encoding.UTF8.GetBytes 的私钥的字符串内容格式不正确。要隔离此原因,您可以尝试将加载的 MemoryStream 保存到文件中,如下代码并将其与 C:\myfile.ppk.

进行比较
memoryStream.CopyTo(fileStream);

I plan on hosting the key in string format in an azure storage table, but am open to other ideas

据我所知,对于托管在 Azure Web App 上的 Web 应用程序,您可以利用 app settings 来存储键值对,这些键值对可以自动加载并覆盖 web.config 中的现有应用程序设置在 运行 时归档。

此外,您可以利用 Azure Blob storage 来私密存储您的私钥文件并按如下方式检索它:

using(var ms=new MemoryStream())
{
   cloudBlockBlob.DownloadToStream(ms);
   var pk = new PrivateKeyFile(ms, "{password}"); 
}

注意:您可以按照此 tutorial 中的 "Encrypting blob data" 部分在客户端和服务器端加密您的 blob 数据。

此外,您可以利用 Azure Key Vault to store your private key. More details, you could refer to this official document 开始使用 Azure Key Vault。

以上回答对我有帮助。我遇到了完全相同的问题,直接从文件读取有效但无法使内存流工作。每次都会报错"invalid private key"。

我将文件读入内存流的方式是这样的:

byte[] bytes = ReadSSHKeyFromDatabase();
MemoryStream ms = new MemoryStream();
ms.Read(bytes, 0, bytes.Length);
Renci.SshNet.PrivateKeyFile pkf = new Renci.SshNet.PrivateKeyFile(ms, Password);

但是我通过将其更改为以下来让它工作:

byte[] bytes = ReadSSHKeyFromDatabase();
MemoryStream ms = new MemoryStream(bytes);
Renci.SshNet.PrivateKeyFile pkf = new Renci.SshNet.PrivateKeyFile(ms, Password);