With WinSCP confirming that the access works in general,
and the assumption that the OpenSSH key format was properly extracted from WinSCP/Putty .ppk format:
example
The private key file must be in this format:
-----BEGIN OPENSSH PRIVATE KEY-----
…
-----END OPENSSH PRIVATE KEY-----
The extension is typically .pem or .key – but does not matter for this usecase.
I suggest to use the full path and filename
Whenever a file is used in an automation, I go 1 extra step and do not supply a string with the (relative) path/filename to any activity that expects a file.
Rather I always use a variable of type FileInfo, and then supply its property .FullName to the activity. Not only will that give an absolute path, but has the benefit:
Initializing a FileInfo (either by UiPath.Core.Activities.GetFileInfoX or in an Assign on the right side with new System.IO.FileInfo) a whole lot of extra properties and validation happens.
Used within a sequence or workflow I find a FileInfo has nothing but advantages. (I try to avoid to use it as a output argument as it might become too big in memory, but that is another topic.)
It is too easy to “loose” a file in C:\ or in .nuget or somewhere else. Not only key files, also .xlsx or .json or .csv: One extra step and .FullName is much more robust.
I recommend to place files with public or private keys in the Windows user’s .ssh directory:
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh")
Because access to C:\ or C:\Temp is open to any user who may log onto the Robot, and an ITSec audit will make us LowCoders look amateurish.
Not sure if the path to the private key is the root cause of your problem, but one likely candidate.
And a minimal example project with the bare dependencies also works wonders.
Rounding off the secure FTP topic:
- a private key file must never be stored in the process repo, no matter if protected by passphrase or not. Again, an ITSec scan of your repo will report this file very prominently.
- in the UiPath ecosystem the key file can be stored securely as a credential in the Orchestrater in the “password” field as a base64 encoded string
- then use InvokeMethod System.IO.File WriteAllBytes to write a on-the-fly casted credential into the filesystem
Convert.FromBase64String(new System.Net.NetworkCredential(String.Empty, SshKeyfileBase64).Password.ToString)
The InvokeMethod above is expected to write a file, beginning and ending with
-----BEGIN OPENSSH PRIVATE KEY-----
…
-----END OPENSSH PRIVATE KEY-----
How to convert text to base64?
- copy the text inside the ‘OpenSSH Private Key Format’ file into the clipboard
- convert
a) use “C:\Program Files\PortableGit\git-bash.exe”: cat /dev/clipboard | base64
b) use PowerShell: [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-Clipboard -Raw)))
- store in the Orchestrator credential as “password”