Programmatically generate SSH Keypairs ( c# windows ) - c#

I'm looking to generate ssh keypairs in open SSH format via code within my web-app (hosted in windows machine) instead of having to manually create it using puttygen.
So, far I've not found any free library that can do this. (There doesn't seem to be a ssh-keygen equivalent for windows.) I am aware of the Cygwin route but I'm trying to avoid this as this would involve having to install cygwin on any servers hosting the app making it not ideal.
What are my options? Will I have to extract out the key-gen function from putty-gen-source and re-write it in c#?

RSA rsa = new RSACryptoServiceProvider(2048);
string publicPrivateKeyXML = rsa.ToXmlString(true);
string publicOnlyKeyXML = rsa.ToXmlString(false);
and then you can parse the XML using XML reader or XML document to get the value you want.

Related

.net standard x509 operating system differences

I have a DLL which creates a signature based off a JSON. The signing is used with X509 self signed certificate with a public \ private keys (.crt and .pfx files), the DLL is using the private key (pfx file) to sign the data.
This DLL is used twice: once in my actual project, which runs on a linux container, and once in my local tests project, which runs on my windows machine.
There is a second DLL uses the public key to verify the signature (crt file).
Here's the thing: the signature created in my test project matches the signature created in my verifier project, both are windows machines. The project on the linux machine signs differently.
What is going on here?? I have several directions:
Different newlines between linux and windows: I have changed the signing DLL so that it takes the JSON string, deserializes into Newtonsoft.JSON object, serializes again with flag Formatting.None, and then deserializes for the final time. This did not help.
Different invisible characters \ encoding: my code is calling UTF8.GetBytes internally on the string, so don't think it's that.
Additionaly, I took the literall byte array from the linux machine into the windows machine, and got different signatures.
Which leads me to think, is the library System.Security.Cryptography.Xml(5.0.0) behaves differently between the OSs? this page says yes, but does not say how:
Cryptographic operations in .NET Core and .NET 5 are done by operating system (OS) libraries. This dependency has advantages
Any ideas as to why this is happening, and maybe a solution?
My signer code:
...
JToken data = JToken.Parse("{}") //obviously a different string
var certificate = new X509Certificate2(...);
var rsaCSP = new RSACryptoServiceProvider();
rsaCSP.FromXmlString(certificate.PrivateKey.ToXmlString(true));
var signatureBytes = rsaCSP.SignData(Encoding.UTF8.GetBytes(data.ToString(), CryptoConfig.MapNameToIOD(...));

Unable to cast error using Box-created RSA key with Box C# SDK project

Our organization recently adopted Box to replace Windows shared folders. The small development group I'm a part of will need to upload and download files from at least one Box share and so we are just getting started with the API.
Our group currently uses Visual Studio 2013 to develop in C# with a preferred target of .NET 4.0. The current version of the SDK (2.15.6) isn't compatible with our platform but looking at prior versions it appears we should be able to leverage version 2.12.1 with our existing platform. The SDK includes a solution with C# methods to access the API calls and a solution with sample code.
Presently I'm trying to get the sample code to consume my credentials and authenticate to the server.
Within the Box developer tools I have created an application and used the built-in Box configuration option to generate a Public/Private keypair which is presented as a JSON file.
Where I'm getting hung up is when I try to use the keypair with the Box.V2.Samples.JWTAuth project. I copied the private key out of the JSON file, replaced the \n's with actual carriage returns, and pasted it into the private_key.pem file:
Private Key
I placed the other values in app.config and started the console app, which produces an Unable to cast error:
Error message
How can I get from a BouncyCastle RsaPrivateCrtKeyParamaters object to a BouncyCastle AsymmetricCipherKeyPair object?
Edit
I was able to track down the problematic code block. From SDK\Box.V2.JWTAuth\BoxJWTAuth.cs:
var pwf = new PEMPasswordFinder(this.boxConfig.JWTPrivateKeyPassword);
AsymmetricCipherKeyPair key;
using (var reader = new StringReader(this.boxConfig.JWTPrivateKey))
{
key = (AsymmetricCipherKeyPair)new PemReader(reader, pwf).ReadObject();
}
var rsa = DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)key.Private);
this.credentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
From my reading it seems like the code is anticipating having to extract the Private key from a Public/Private pair which isn't what Box is supplying (at least, not currently) and what I'm supplying appears to already be of the RsaPrivateCrtKeyParameters type so this cast may (no longer be) necessary.
It's not clear from your question whether you are trying to write code to do this, or trying to configure a tool, but programmatically, it would be:
RSAPrivateCrtKeyParameters priv = ...;
RSAKeyParameters pub = new RSAKeyParameters(false, priv.getModulus(), priv.getPublicExponent());
AsymmetricCipherKeyPair kp = new AsymmetricCipherKeyPair(pub, priv);

Secure parameters with powershell exec

I have a Powershell app that retrieves some secret data- then needs to execute a .NET exe (locally) passing that data. It appears that passing the data as a raw param could expose it to users on the machine, so I'm looking for a way to keep it secure.
Possible solutions-
Get the data directly from the C# app (possible, but not ideal)
Put the data in an EFS encrypted file and pass the file location
Encrypt the param with a shared key (something built into windows?)
Any tips/guidance would be appreciated.
Please see this Microsoft Technet article:
Working With Passwords and Secure Strings in Windows Powershell
The gist of the above article:
Basic example of encrypting a string:
$PlainParam = "param you want to encrypt"
$SecureParam = $PlainParam | ConvertTo-SecureString -AsPlainText -Force
Cmdlets to look into:
ConvertTo-SecureString
ConvertFrom-SecureString

How to openssl passwd -1 in C# against MySQL

I am making one extension for iRedMail server, I want to add new user using C# code.
IrerdMail holding users inside MySQL database, passwords of users are encrypted using openssl (MD5).
When I look at iRedMail api for creating users there is line of code inside bash script:
openssl passwd -1 passwordToBeEncrpted
That command inside terminal return me MD5 string, If I copy that string to my app and execute insert command against MySQL table hosted on mail-server created user works OK.
What will be proper way to generate MD5 from user password so I can insert that to MySQL database ?
My app running on other server beside iRedMAil, Is it obligatory to MD5 be created on the same machine ?
I am considering calling SSH command from C# code , Is there free .NET library which can reuse output stings from SSH as variables ?
Can this be done using something like UDF like in MSSQL server. I know how I cloud call command app from MSSQL does something like that exist at MySQL - CentoOS combination.
Just an idea: instead of trying to call openssl (which users will have to install, or you have to include in your installation procedure) with all the associated hassle it might be preferable to just port over the original C source for crypt.
This will take you some time to get right, but IMO your program will be a lot simpler, more robust and more compact to install.
EDIT: have a look at this question here on SO: Problem porting PHP crypt() function to C# - the code he wrote was meant to be compatible with BSD crypt, so it might be just what you need.. I just tested it in Visual Studio 2010 and compared to the output of openssl on a Linux box here, and the outputs match.
My open-source library CryptSharp (since 2.0) supports MD5 crypt. The syntax is:
string cryptedPassword = Crypter.MD5.Crypt("password");
Should do what you need.
James

Automate SSH login under windows

I want to be able to execute openssh with some custom arguments and then be able to automatically login to the server. I want that my script will enter the password if needed and inject 'yes' if I'm prompted to add the fingerprint to the known hosts.
I've found SharpSsh for C# that do that, but I also need to use -D parameter and use ProxyCommand that I define in SSH, and the library is quite lacking for that usage.
Another thing that I've found was pexcept for Python that should do the trick but I couldn't find where to download it, on the offical page I'm being redirectred from sourceforge to some broken link.
Any help would be appreciated,
Bill.
If you use OpenSSH and then have a script to inject password in clear (meaning, you have stored the password unencrypted) it is defeating the purpose of secure shell.
Please strongly consider using public key mechanisms which can be easily and securely automated.
I'll second the recommendation to use public key authentication. Rather than hack around with expect, you might want to consider Paramiko - it's a native SSH client for Python which would greatly simplify the communications process, particularly if you ever need to interact with the remote server and it has support for things like SFTP built-in.
i use pexpect for similar purpose and download also work?
http://sourceforge.net/project/downloading.php?group_id=59762&filename=pexpect-2.3.tar.gz
here is a portion fro my ssh automate script, you can customize it for you usage
it may not run out of the box
import os
import getpass
import pexpect
import glob
import logging
import shutil
import time
class UpdateError(Exception): pass
g_password = None
def runSshCommand(cmd):
global g_password
ssh_newkey = 'Are you sure you want to continue connecting'
# my ssh command line
p=pexpect.spawn(cmd)
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==0:
print "Saying yes to connection.."
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
while True:
if g_password is None:
g_password = getpass.getpass("password:")
p.sendline(g_password)
i = p.expect(['password:',pexpect.EOF])
if i==0:
g_password = None
print "Wrong password"
else:
break
elif i==2:
raise UpdateError("Got key or connection timeout")
return p.before
There is some excellent documentation on using Putty with generated SSH key authentication. This is an easy and secure way to accomplish your goals. Putty has a great set of features, for a windows SSH app. Even better when you consider that you can get it on the free.
pexpect can't import on Windows. So, I use plink.exe with a Python subprocess to connect to the ssh server.
Another way is to to use openssh and establish a trusted key; if both client and the user account on the server have this key, then openssh does not request a password.
I have a script that automates setup of this - it works under cygwin,
http://mosermichael.github.io/cstuff/all/projects/2011/07/14/ssh-friends.html
I hope Net::SSH::Expect Perl module will be of help to you.

Categories

Resources