使用Renci.SshNet调用新密钥遇Permission denied(publickey)问题求助
用Renci.SshNet写的C#控制台应用连接SSH,切换到生产环境的公私密钥后,抛出Renci.SshNet.Common.SshAuthenticationException: Permission denied (publickey)异常。但这套密钥在终端、Python代码里正常能用,之前用Putty生成的密钥在C#代码里也没问题。
用到的代码:
try { var privateKeyFile = new PrivateKeyFile(privateKeyFilePath); var privateKeyAuth = new PrivateKeyAuthenticationMethod(username, privateKeyFile); var sshClient = new SshClient(connectionInfo); sshClient.Connect(); // 执行SSH操作示例 SshCommand sshCommand = sshClient.RunCommand("ls -l"); string commandResult = sshCommand.Result; Console.WriteLine(commandResult); sshClient.Disconnect(); sshClient.Dispose(); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); }
转换密钥格式:Renci.SshNet对新版OpenSSH格式密钥(开头是
-----BEGIN OPENSSH PRIVATE KEY-----)支持可能有问题,转成PEM格式再试:
打开终端跑这条命令:ssh-keygen -p -m PEM -f /path/to/your/private_key,跟着提示输密码(如果有),转换后的密钥再给C#代码用。检查密钥文件权限:Windows下虽然没Linux严格,但别让密钥文件权限太开放,只给当前用户读写权限,防止系统判定为不安全密钥被拒。
确认ConnectionInfo初始化正确:代码里的
connectionInfo得把PrivateKeyAuthenticationMethod传进去,比如:var connectionInfo = new ConnectionInfo(host, port, username, privateKeyAuth);别漏了把认证方法关联到连接信息里。
开日志查细节:打开Renci.SshNet的日志,看认证时的具体错误:
// 加在Connect()之前 Renci.SshNet.Logging.Logger.LogLevel = Renci.SshNet.Logging.LogLevel.Debug; Renci.SshNet.Logging.Logger.Log += (sender, e) => Console.WriteLine($"[{e.Level}] {e.Message}");日志里能看到服务器拒绝的具体原因,比如密钥类型不支持、签名算法不对之类的。
处理密钥密码短语:如果生产环境密钥设了密码,创建PrivateKeyFile时要显式传密码:
var privateKeyFile = new PrivateKeyFile(privateKeyFilePath, "your_passphrase");终端和Python可能自动读了缓存的密码,但C#代码得手动传。
检查服务器端配置:确认服务器上
~/.ssh/authorized_keys里有对应的公钥,而且文件权限是600,目录权限700,权限不对服务器也会拒认证。
内容的提问来源于stack exchange,提问作者SIbghat

