Kon*_*ram 5 .net c# ssh sftp ssh.net
我正在尝试使用SFTP将文件发送到某些服务器。在此过程中,我遇到了异常
Renci.SshNet.Common.SshException:无效的私钥文件。在Renci.SshNet.PrivateKeyFile.Open(Stream privateKey,String passPhrase)
使用PuTTYgen生成了密钥,如下所示是私钥文件的示例格式。它同时具有公共密钥和私有密钥。
PuTTY-User-Key-File-2: ssh-rsa
Encryption:none
comment: rsa-key-20190327
Public-Lines: 4
AAAAB.....
......
Private-Lines: 8
AAAAgQ......
.......
Private-MAC: 54901783....
Run Code Online (Sandbox Code Playgroud)
我将上述文件中的私钥部分复制到了配置文件中,并按照SftpKey
我的代码进行访问。
得到了上述密钥的OpenSSH格式,看起来像
------BEGIN RSA PRIVATE KEY-----
MIIE....
.......
------END RSA PRIVATE KEY-------
Run Code Online (Sandbox Code Playgroud)
我只复制了上面文件中的关键部分,然后复制到我的配置文件中,然后运行了我的代码。问题尚未解决。
以下是我用于SFTP上传的代码
var fileLength = data.Length;
var keyStr = ConfigurationManager.ConnectionStrings["SftpKey"].ConnectionString;
using (var keystrm = new MemoryStream(Convert.FromBase64String(keyStr)))
{
var privateKey = new PrivateKeyFile(keystrm);
using (var ftp = new SftpClient(_ftpServer, _ftpUser, new[] { privateKey }))
{
ftp.ErrorOccurred += ErrorOccurred;
ftp.Connect();
ftp.ChangeDirectory(_ftpPath);
using (var dataStream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
{
ftp.UploadFile(dataStream, Path.GetFileName(message.MessageId), true,
(length) => result = fileLength == (int)length);
}
ftp.Disconnect();
}
}
Run Code Online (Sandbox Code Playgroud)
代码有什么问题吗?或者可能是问题所在?任何帮助深表感谢。
Mat*_*emp 20
由于这是该错误消息的最佳答案,因此我认为值得扩展原始问题中的一点 - 转换为 OpenSSH 格式的密钥。
Renci.SshNet 不能使用以下开头的 PuTTY 密钥:
PuTTY-User-Key-File-2: ssh-rsa
Run Code Online (Sandbox Code Playgroud)
可以使用 puttygen.exe 转换为 OpenSSH 格式
这将生成一个以以下内容开头的密钥:
-----BEGIN RSA PRIVATE KEY-----
Run Code Online (Sandbox Code Playgroud)
这会起作用
我只复制了上面文件中的关键部分
您需要在MemoryStream
. 并且与文件中完全一样(就像您使用FileStream
文本密钥文件一样)。所以没有Convert.FromBase64String
。
var keyStr = @"-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAiCYlBq7NITBpCCe48asfXKMpnJJJK+7FQj6wIRJCNuBk76tL
jNooDDPPrnrE9VKxRds4olPftjRj87s9gjm4EirbvijZ9PoDlW9CWFhjJPwCPJpA
onkhaiA7SV+abRDQHm/lst5Fk9tzl+DZcS/EleilGDV7rCYEP692UJRsi3GvzngQ
dpRvVvO4o2rXnEkdp+254KHsah0pSxri23+jqbxPguHKGIMylrswokMI0QKcfm+1
/pjrV64EQCxli3i2yPl4WVh/QaNyHMKoze/WN00Pia99QhE1Rm3YCCarFWFeX+R5
7LgIUhtrE7vZGvimfZN7oBdR2pEq10PIc+8q9QIBJQKCAQAWFAYBFW1fU/VbRLY1
Bv4qsqzNSCeKlWwYlItDohiTRvucfKR3tKyMW23JRFdKYG/GI4yks6e8roy/vX+Y
k7z8BvMzl+v+NmFyLbe7TJp0sz6iCy0TbZa3Q388VLFCHmbwLdI4rmwl0I9JD7SO
5SbMM5BkymcU/z71khMvqV21vym5Ge/ApvX0K0XNJs/N/OLnX46Z8taYEyTmreSR
rxAbma4I5BhqXbH0CMOI5u8zCyycghytl5sYyMr+LIWQKWLzQU+mPNN0qIy0pO5t
r8lGNJh5Lnmu1lQw9yAGo2IPPIERP90X64pVrteIjPtt30n87bWDS8gOiam8S/qk
2ZJVAoGBAPZi6E/KpYpzYGKPAfialu0QN1X7uFio1MUmDum+phk5+xeQb/VvlP6Y
d+/o03EMnhvUsop9p7E2CwLZfT6DO7x3LKtumfceq5dPE5hQSWXi9RkBhcOJaZvZ
z+36c8N8iSZZzlxdA5TeDTUqtuVli4HLrcsXaAaVMxEr/G2JwUgTAoGBAI12Gnoy
k/gsiHz4pDLgxWQE6R8vkBMXfQCWhkzvzKca4twQ8z4ZAb/yt+BCiioJn5g58CVS
dP2zd3Lx8e9kkxggZLcUR3Ao6HceYKeD6mx4vkpHiyCtKJI+qfnkw2A64xwbtvTR
h/O5Aq90SjqP4YcaK9E0W/mWYoL3ctFG8DHXAoGBAKZ6LkPARlag+++RDytvXw7h
cX9JN15/6bWkF+oLMfVehw/r+J7qh0Q9gXiWZVo49TVmM3JU5u1b3e0rKxxmgk7o
vVE85JI3UVhl3M6yyc84fBfQmKa2ytEWoT/uaeTzR+l68zd9Hhh6W/N9udlEnIgh
1kr0I7FruriTV4hIUinHAoGASKRudhn49Q/zD73zdBKO4FWMd8xQ5zWTN6c+C9UW
EJ8ajK7CGPgVp8HUC2BwdnOk+ySrwCNsgkdm2ik3DDqQuVy+GNMP7XzKZq68Av6N
IvHlLQ/7VfgN6jvavpgRTRdSB4Pafbe0hBLltAtItknig6WnzEtR0zGMiHE69dhR
1GcCgYBckoyMXpT0HzOjLXWClSiIaDDfgGcmgEKbYJ7c3mncjLinbCVFdJ0UcrqJ
tiauWBvmecAhnJvQGnmInawNUHetAgJoCbqd7cckjI8VtBgHlQyT93wo9fSDz0Kt
dDHspRvVQkhiR/6IWz1PtCT0QGrHP8fJq/PCbLnJf/EJqJv/xA==
-----END RSA PRIVATE KEY-----
";
using (var keystrm = new MemoryStream(Encoding.ASCII.GetBytes(keyStr)))
{
var privateKey = new PrivateKeyFile(keystrm);
}
Run Code Online (Sandbox Code Playgroud)
实际上,在我展示的较早代码中,存在成功发送文件的现有实现。
那么您的连接字符串不包含您声称的内容。检查 的执行情况PrivateKeyFile.Open
。它明确检查流是否以---- BEGIN ... PRIVATE KEY
. 如果不是,它会抛出“无效的私钥文件”。
实际上甚至不可能(或难以)将多行内容存储到连接字符串中。如果您的代码曾经工作过,那一定是因为您的SftpKey
连接字符串包含一个完整的密钥文件(包括BEGIN ... PRIVATE KEY
信封),但(再次)以Base64 编码(作为一行)进行编码。像这样:
Convert.ToBase64String(File.ReadAllBytes(@"C:\path\to\key"))
Run Code Online (Sandbox Code Playgroud)
这会给你这样的字符串:
var keyStr = @"-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAiCYlBq7NITBpCCe48asfXKMpnJJJK+7FQj6wIRJCNuBk76tL
jNooDDPPrnrE9VKxRds4olPftjRj87s9gjm4EirbvijZ9PoDlW9CWFhjJPwCPJpA
onkhaiA7SV+abRDQHm/lst5Fk9tzl+DZcS/EleilGDV7rCYEP692UJRsi3GvzngQ
dpRvVvO4o2rXnEkdp+254KHsah0pSxri23+jqbxPguHKGIMylrswokMI0QKcfm+1
/pjrV64EQCxli3i2yPl4WVh/QaNyHMKoze/WN00Pia99QhE1Rm3YCCarFWFeX+R5
7LgIUhtrE7vZGvimfZN7oBdR2pEq10PIc+8q9QIBJQKCAQAWFAYBFW1fU/VbRLY1
Bv4qsqzNSCeKlWwYlItDohiTRvucfKR3tKyMW23JRFdKYG/GI4yks6e8roy/vX+Y
k7z8BvMzl+v+NmFyLbe7TJp0sz6iCy0TbZa3Q388VLFCHmbwLdI4rmwl0I9JD7SO
5SbMM5BkymcU/z71khMvqV21vym5Ge/ApvX0K0XNJs/N/OLnX46Z8taYEyTmreSR
rxAbma4I5BhqXbH0CMOI5u8zCyycghytl5sYyMr+LIWQKWLzQU+mPNN0qIy0pO5t
r8lGNJh5Lnmu1lQw9yAGo2IPPIERP90X64pVrteIjPtt30n87bWDS8gOiam8S/qk
2ZJVAoGBAPZi6E/KpYpzYGKPAfialu0QN1X7uFio1MUmDum+phk5+xeQb/VvlP6Y
d+/o03EMnhvUsop9p7E2CwLZfT6DO7x3LKtumfceq5dPE5hQSWXi9RkBhcOJaZvZ
z+36c8N8iSZZzlxdA5TeDTUqtuVli4HLrcsXaAaVMxEr/G2JwUgTAoGBAI12Gnoy
k/gsiHz4pDLgxWQE6R8vkBMXfQCWhkzvzKca4twQ8z4ZAb/yt+BCiioJn5g58CVS
dP2zd3Lx8e9kkxggZLcUR3Ao6HceYKeD6mx4vkpHiyCtKJI+qfnkw2A64xwbtvTR
h/O5Aq90SjqP4YcaK9E0W/mWYoL3ctFG8DHXAoGBAKZ6LkPARlag+++RDytvXw7h
cX9JN15/6bWkF+oLMfVehw/r+J7qh0Q9gXiWZVo49TVmM3JU5u1b3e0rKxxmgk7o
vVE85JI3UVhl3M6yyc84fBfQmKa2ytEWoT/uaeTzR+l68zd9Hhh6W/N9udlEnIgh
1kr0I7FruriTV4hIUinHAoGASKRudhn49Q/zD73zdBKO4FWMd8xQ5zWTN6c+C9UW
EJ8ajK7CGPgVp8HUC2BwdnOk+ySrwCNsgkdm2ik3DDqQuVy+GNMP7XzKZq68Av6N
IvHlLQ/7VfgN6jvavpgRTRdSB4Pafbe0hBLltAtItknig6WnzEtR0zGMiHE69dhR
1GcCgYBckoyMXpT0HzOjLXWClSiIaDDfgGcmgEKbYJ7c3mncjLinbCVFdJ0UcrqJ
tiauWBvmecAhnJvQGnmInawNUHetAgJoCbqd7cckjI8VtBgHlQyT93wo9fSDz0Kt
dDHspRvVQkhiR/6IWz1PtCT0QGrHP8fJq/PCbLnJf/EJqJv/xA==
-----END RSA PRIVATE KEY-----
";
using (var keystrm = new MemoryStream(Encoding.ASCII.GetBytes(keyStr)))
{
var privateKey = new PrivateKeyFile(keystrm);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2280 次 |
最近记录: |