SshNet问题与流式私钥

时间:2017-01-08 16:52:37

标签: c# azure ssh

我正在使用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的错误,但显然文件流有效。我计划在天蓝色存储表中以字符串格式托管密钥,但我愿意接受其他想法。

2 个答案:

答案 0 :(得分:3)

根据您的描述,我使用PuTTYgen生成了我的私钥文件,并通过引用此tutorial将我的密钥转换为OpenSSH格式。根据您提供的有关使用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);
  

我计划在天蓝色存储表中以字符串格式托管密钥,但我愿意接受其他想法

众所周知,对于Azure Web App上托管的Web应用程序,您可以利用app settings来存储键值对,这些键值对可以在运行时自动加载并覆盖web.config文件中的现有appsettings-时间。

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

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

注意:您可以按照此tutorial中的“加密blob数据”部分来加密客户端和服务器端的blob数据。

此外,您可以利用Azure Key Vault存储您的私钥。有关详细信息,您可以参考此官方document以获取Azure Key Vault入门。

答案 1 :(得分:0)

以上答案对我有所帮助。我有一个完全相同的问题,直接从文件读取可以工作,但无法获取内存流。每次都会显示错误“私钥无效”。

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

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);