I'm planning to write some software using SFTP with public/private key authentication to upload files to a server. I am wondering how people recommend managing the keys (especially the private key).
My target platform is Windows with C# or C++. I've looked at a number of libraries:
C#
(free/open) SharpSSH Granados(commercial)
RebexC++
libcurl/OpenSSHAll of these appear to require the private key to be stored on the filesystem, which I would prefer to avoid for security reasons. I would also prefer not to implement the authentication myself although I recognize that as an option. My questions:
Is there a way to feed any of these libraries (or any library/API I may have overlooked) the开发者_StackOverflow中文版 key values directly from memory instead of loading from a file?
If not, what is the recommended way to manage these key files? Beyond password encryption and tight access control, are there other things one should do to protect the key file?
All of these appear to require the private key to be stored on the filesystem, which I would prefer to avoid for security reasons.
I think you should embrace the filesystem. Modern ones such as NTFS (which as a Windows developer you are almost surely using) have robust security mechanisms which are probably better thought out than most any alternative mechanism you (or I) might devise. NTFS has access control lists, encryption, and so on--if you can't trust your filesystem to keep your data safe, why do you even bother caring about network traffic?
I'll note that there are some specific circumstances which could preclude doing what I've said above, but I don't see any of them mentioned in the original post.
I've never used Granados, but that library's SSH2UserAuthKey class has a FromSECSHStyleStream
method that loads a user's authentication key from an arbitrary Stream
(which could be a MemoryStream
if you want to load the key directly from memory). It seems like this would let you bypass the filesystem for key storage.
Rebex.Net has a SshPrivateKey class constructor that can load from a byte[]
; this should also let you avoid the filesystem.
While I haven't checked the other libraries, it seems likely that all of them would provide methods to load a key from a byte[]
, MemoryStream
, or unsigned char*
, with convenience methods that load directly from a file.
These APIs don't solve the problem of how the private key will actually be stored, though. You could password-protect it (this seems a fairly common approach with SSH private keys) or use the ProtectedData class to encrypt it with the current Windows user's credentials.
SFTP classes of SecureBlackbox (our product) let you load the key from any stream or byte array. Moreover, they also let you generate and convert SSH keys in various formats.
If you have questions, we provide support to evaluating users via Forum and HelpDesk
Following code shows how to authenticate using a private key using Rebex SFTP.
Code is taken from following forum post. For more info check SFTP tutorial.
// create client and connect
Sftp client = new Sftp();
client.Connect(hostname);
// instead of loading it from disk file load the private key from a byte array
//SshPrivateKey privateKey = new SshPrivateKey("key_rsa.pem", "password");
byte[] privateKeyData = YourMethodForObtainingPrivateKey();
SshPrivateKey privateKey = new SshPrivateKey(privateKeyData, "password");
// authenticate
client.Login(username, privateKey);
// ...
精彩评论