Post a reply

Options
Add an Attachment

If you do not want to add an Attachment to your Post, please leave the Fields blank.

(maximum 10 MB; please compress large files; only common media, archive, text and programming file formats are allowed)

Options

Topic review

martin

Re: PPKs stored in Azure Key Vault

@olinton: Thanks for sharing this.
olinton

PPKs stored in Azure Key Vault

I've referred to this forum and this post multiple times recently in support of an Azure function I've been working on and just wanted to add a resource which I found helpful for storing .ppk's in an Azure Key Vault. From what I understand, manually adding the plaintext value of the .ppk to the key vault messes the formatting so it has to be done programmatically which I did using Azure CLI, as follows:
Set-AzKeyVaultSecret -VaultName my-key-vault-name -Name SshPrivateKey -SecretValue (ConvertTo-SecureString (Get-Content ./SshPrivateKey.ppk -Raw) -force -AsPlainText)


I adapted that snippet from the reference below in, adding my .ppk file with the name SshPrivateKey and access it using standard Key Vault libraries:

static string GetSecretFromKeyVault(string secretName)
{
    var keyVaultUrl = "https://mykeyvault.vault.azure.net/";
    var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
    KeyVaultSecret secret = client.GetSecret(secretName);
    return secret.Value;
}

...
string SshPrivateKey = GetSecretFromKeyVault("SshPrivateKey");
...
 
SessionOptions sessionOptions = new SessionOptions
{
    ...
    SshPrivateKey = SshPrivateKey,
    ...
};


Hopefully that's helpful for anyone else that needs to figure this out in the future.
Ref: Storing SSH & PGP Keys in Azure Key Vault – BrownBot
martin

Re: Read private key from string (not file)

@AKG: No @ prefixing. No hex encoding. That's needed in scripting only. In .NET assembly, just pass the contents of your key file to SessionOptions.SshPrivateKey as it is, as @randallg has shown. No special encoding.

If this works:
sessionOptions.SshPrivateKeyPath = @"C:\path\key.ppk"

Then this does the same:
sessionOptions.SshPrivateKey = File.ReadAllText(@"C:\path\key.ppk")
randallg

Re: Read private key from string (not file)

@AKG: In my case the key file is stored as a resource in my .NET assembly.
I know nothing of the format of the ppk file, it is plain text generated for you and looks like this:
PuTTY-User-Key-File-2: ssh-rsa

Encryption: none
Comment: rsa-key-20200928
Public-Lines: 6
AAAAB3NzaC1yc2EAAAABJQAAAQEAtLcfmQXeqb3Bk5dNoKAQ1gvZScMnrbGkRvsJ
...  more lines like the above


I access in code like this:
void open()
{
   if (session != null) return;
   string key;
   using (Stream keystream = Assembly.GetExecutingAssembly().GetManifestResourceStream(StockwatchPpkResource)) {
      key = new StreamReader(keystream).ReadToEnd();
   }
   session = new Session {
      DisableVersionCheck = true
   };
   SessionOptions sessionOptions = new SessionOptions {
      Protocol = Protocol.Sftp,
      HostName = StockwatchHost,
      UserName = StockwatchUser,
      SshHostKeyFingerprint = StockwatchSshHostKeyFingerprint,
      SshPrivateKey = key
   };
   session.Open(sessionOptions);
}
AKG

Re: Read private key from string (not file)

Hi, I have tried passing the ssh key as a string but always getting error: Unable to use key file "in-memory" (not a recognised key file format).

I have tried many combinations, tried converting it in Hex string, prefixed with @, but every time getting the same error. While through file it is working fine.

Could you please help me with an example, like what part of ppk file and in which format we need to pass for this feature?

Thanks in advance.
randallg

Re: Read private key from string (not file)

@ashishr10: Yes this feature is in the latest release.
ashishr10

Re: Read private key from string (not file)

Hi, is it available now? This feature.
martin

Re: Read private key from string (not file)

@randallg: I'm sending you an email with a development version of WinSCP to the address you have used to register on this forum.
martin

Re: Read private key from string (not file)

@randallg: Thanks for your donation! I'll look into it.
randallg

Re: Read private key from string (not file)

I just voted for this change. I also donated so that is 4 more votes for!
In our case we store the file in the .NET assembly as a resource, but I would like to avoid having to write it to disk every time.
void open()
{
   string keyfile = Path.GetTempPath() + Guid.NewGuid().ToString() + ".ppk";
   using (var keystream = Assembly.GetExecutingAssembly().GetManifestResourceStream(StockwatchPpkResource)) {
      Util.SlopFile(keyfile, new StreamReader(keystream));
   }
   session = new Session();
   session.DisableVersionCheck = true;
   SessionOptions sessionOptions = new SessionOptions {
      Protocol = Protocol.Sftp,
      ... other stuff
      SshPrivateKeyPath = keyfile,
   };
   session.Open(sessionOptions);
   File.Delete(keyfile);
}
matrixiux

+1 I was very surprised that WinSCP is not considering this feature...
bobbabooie

Re: Read private key from string (not file)

@martin: I'd upvote this. It's arguable that it may be more secure to pass the key as a string of text rather than having it persisted to a file. In our case we're using SSIS to call winscp.com and we have secure variables in SSIS. If I have to persist it to a file, then that creates more "surface area" that we have to manage securely (make sure it gets deleted, make sure the file as proper permissions and/or in a location that's not accessible to those that shouldn't have read access, etc). I'm not an expert but it might be something to look at.. sort of treat it like a password parameter, since that's how things are going these days (key-based auth).
martin

Re: Read private key from string (not file)

It's not on the road map, as it's not frequently requested, sorry.
matrixiux

Do you know if that's on the road map, or would be considered? We already have existing services running WinSCP in the code, but this feature made us re-develop for an alternative library.
matrixiux

Read private key from string (not file)

We are storing our Private SSH Key in Azure Key Vault.
We retrieve it as a string, where string the whole key.
WinSCP COM library only allows adding SshPrivateKeyPath in the SessionOptions.

Now we don't want to write out the key in a text file, as that would beat the purpose of storing the key in to Azure Key Vault, for security reasons.

Is there a hidden way to load the key as a string or similar, and not a a physical file?

Azure Key Vault is client's requirement.