Reputation: 382
I need to generate a key pair for the authentication in a ssh tunnel with C#.
The only constraint is the cryptographic that should be Ed25519.
I'm able to generate a valid public key but not a valid private key (or maybe only the format).
I've tried with BouncyCastle and NSec libraries for generate them with no success.
Here some of my attempts:
#### NSec ####
var creationParameters = new KeyCreationParameters
{
ExportPolicy = KeyExportPolicies.AllowPlaintextArchiving
};
using (var key = Key.Create(SignatureAlgorithm.Ed25519, creationParameters))
{
var blob = key.Export(KeyBlobFormat.PkixPrivateKeyText);
result.PrivateKey = Convert.ToBase64String(blob);
blob = key.Export(KeyBlobFormat.PkixPublicKeyText);
result.PublicKey = string.Format("ssh-ed25519 {0} generated-key", Convert.ToBase64String(blob));
}
#### BouncyCastle ####
IAsymmetricCipherKeyPairGenerator gen;
KeyGenerationParameters param;
gen = new Ed25519KeyPairGenerator();
param = new Ed25519KeyGenerationParameters(new SecureRandom());
gen.Init(param);
AsymmetricCipherKeyPair pair = gen.GenerateKeyPair();
PrivateKeyInfo pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private);
result.PrivateKey = Convert.ToBase64String(pkInfo.GetDerEncoded());
SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pair.Public);
result.PublicKey = Convert.ToBase64String(info.GetDerEncoded());
For be more specific I wish obtain a result like the following generation from the cmd:
ssh-keygen -t ed25519 -f ssh-ed25519-private-key.pem
That generate the public key like:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICjTBKzEKElOtmjuYDaBsoF9UpsXUeLUmKuqiK86jv2A xxxxxx\xxxxxxx@xxxx
And the private like:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAo0wSsxChJTrZo7mA2gbKBfVKbF1Hi1JirqoivOo79gAAAAKgLape6C2qX
ugAAAAtzc2gtZWQyNTUxOQAAACAo0wSsxChJTrZo7mA2gbKBfVKbF1Hi1JirqoivOo79gA
AAAECRX7SDurbmPZzRMqYwONep7gk4ZCFp1Uj6hTpVbGWi0CjTBKzEKElOtmjuYDaBsoF9
UpsXUeLUmKuqiK86jv2AAAAAJWNnLWNvbnRyb2xzLXJkXGFtZW5lZ2F0QFcwNTItQU1lbm
VnYXQ=
-----END OPENSSH PRIVATE KEY-----
Thanks,
Andrea
Upvotes: 1
Views: 3242
Reputation: 22926
I'm able to generate a valid public key but not a valid private key (or maybe only the format).
This doesn't make sense.
The public key is really a point (X,Y co-ordinate) on the Elliptic Curve defined by y^2 = x^3 + 486662*x^2 + x
over Finite Field of size 57896044618658097711785492504343953926634992332820282019728792003956564819949
A public key is only able to be obtained by scalar multiplication of the generator point G (9 , 14781619447589544791020593568409986887264606134616475288964881837755586237401)
by a large number. Thus the private key is really just a 256-bit integer, a number.
In it's most raw form a private key is a 256-bit random value, the OpenSSH format above is a base64 encoded value including other components such as:
"openssh-key-v1"0x00 # NULL-terminated "Auth Magic" string
32-bit length, "none" # ciphername length and string
32-bit length, "none" # kdfname length and string
32-bit length, nil # kdf (0 length, no kdf)
32-bit 0x01 # number of keys, hard-coded to 1 (no length)
32-bit length, sshpub # public key in ssh format
32-bit length, keytype
32-bit length, pub0
32-bit length, pub1
32-bit length for rnd+prv+comment+pad
64-bit dummy checksum? # a random 32-bit int, repeated
32-bit length, keytype # the private key (including public)
32-bit length, pub0 # Public Key parts
32-bit length, pub1
32-bit length, prv0 # Private Key parts
... # (number varies by type)
32-bit length, comment # comment string
padding bytes 0x010203 # pad to blocksize
I suggest strongly that you switch to libsodium
, which is the standard when interacting with curve25519
or it's Twisted Edwards signature focused variant, ed25519
.
Upvotes: 1