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