/// <summary> /// reads private key portion of OpenSSH formatted key blob from stream and /// creates a key pair /// </summary> /// <returns>key pair</returns> /// <remarks> /// intended to be called immediately after ParseSsh2PublicKeyData /// </remarks> public AsymmetricCipherKeyPair ReadSsh2KeyData( AsymmetricKeyParameter publicKeyParameter) { if (publicKeyParameter is RsaKeyParameters) { var rsaD = new BigInteger(1, ReadBlob()); var rsaIQMP = new BigInteger(1, ReadBlob()); var rsaP = new BigInteger(1, ReadBlob()); var rsaQ = new BigInteger(1, ReadBlob()); /* compute missing parameters */ var rsaDP = rsaD.Remainder(rsaP.Subtract(BigInteger.One)); var rsaDQ = rsaD.Remainder(rsaQ.Subtract(BigInteger.One)); var rsaPublicKeyParams = publicKeyParameter as RsaKeyParameters; var rsaPrivateKeyParams = new RsaPrivateCrtKeyParameters( rsaPublicKeyParams.Modulus, rsaPublicKeyParams.Exponent, rsaD, rsaP, rsaQ, rsaDP, rsaDQ, rsaIQMP); return(new AsymmetricCipherKeyPair(rsaPublicKeyParams, rsaPrivateKeyParams)); } else if (publicKeyParameter is DsaPublicKeyParameters) { var dsaX = new BigInteger(1, ReadBlob()); // private key var dsaPublicKeyParams = publicKeyParameter as DsaPublicKeyParameters; DsaPrivateKeyParameters dsaPrivateKeyParams = new DsaPrivateKeyParameters(dsaX, dsaPublicKeyParams.Parameters); return(new AsymmetricCipherKeyPair(dsaPublicKeyParams, dsaPrivateKeyParams)); } else if (publicKeyParameter is ECPublicKeyParameters) { var ecdsaPrivate = new BigInteger(1, ReadBlob()); var ecPublicKeyParams = publicKeyParameter as ECPublicKeyParameters; ECPrivateKeyParameters ecPrivateKeyParams = new ECPrivateKeyParameters(ecdsaPrivate, ecPublicKeyParams.Parameters); return(new AsymmetricCipherKeyPair(ecPublicKeyParams, ecPrivateKeyParams)); } else if (publicKeyParameter is Ed25519PublicKeyParameter) { var ed25519Signature = ReadBlob(); var ed25519PrivateKey = new Ed25519PrivateKeyParameter(ed25519Signature); return(new AsymmetricCipherKeyPair(publicKeyParameter, ed25519PrivateKey)); } else { // unsupported encryption algorithm throw new Exception("Unsupported algorithm"); } }
public static SshKey CreateKey(SshVersion version, PublicKeyAlgorithm algorithm, string comment = "") { if (version == SshVersion.SSH1 && algorithm != PublicKeyAlgorithm.SSH_RSA) { throw new Exception("unsupported version/algorithm combination"); } switch (algorithm) { case PublicKeyAlgorithm.SSH_RSA: case PublicKeyAlgorithm.SSH_RSA_CERT_V1: KeyGenerationParameters keyGenParam = new KeyGenerationParameters(secureRandom, 512); var rsaKeyPairGen = new RsaKeyPairGenerator(); rsaKeyPairGen.Init(keyGenParam); var keyPair = rsaKeyPairGen.GenerateKeyPair(); var rsaKey = new SshKey(version, keyPair, comment); return(rsaKey); case PublicKeyAlgorithm.SSH_DSS: case PublicKeyAlgorithm.SSH_DSS_CERT_V1: DsaParametersGenerator dsaParamGen = new DsaParametersGenerator(); dsaParamGen.Init(512, 10, secureRandom); DsaParameters dsaParam = dsaParamGen.GenerateParameters(); DsaKeyGenerationParameters dsaKeyGenParam = new DsaKeyGenerationParameters(secureRandom, dsaParam); DsaKeyPairGenerator dsaKeyPairGen = new DsaKeyPairGenerator(); dsaKeyPairGen.Init(dsaKeyGenParam); keyPair = dsaKeyPairGen.GenerateKeyPair(); var dsaKey = new SshKey(SshVersion.SSH2, keyPair); dsaKey.Comment = comment; return(dsaKey); case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256_CERT_V1: X9ECParameters ecdsa256X9Params = SecNamedCurves.GetByName("secp256r1"); ECDomainParameters ecdsa256DomainParams = new ECDomainParameters(ecdsa256X9Params.Curve, ecdsa256X9Params.G, ecdsa256X9Params.N, ecdsa256X9Params.H); ECKeyGenerationParameters ecdsa256GenParams = new ECKeyGenerationParameters(ecdsa256DomainParams, secureRandom); ECKeyPairGenerator ecdsa256Gen = new ECKeyPairGenerator(); ecdsa256Gen.Init(ecdsa256GenParams); keyPair = ecdsa256Gen.GenerateKeyPair(); var ecdsa256Key = new SshKey(SshVersion.SSH2, keyPair); ecdsa256Key.Comment = comment; return(ecdsa256Key); case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384_CERT_V1: X9ECParameters ecdsa384X9Params = SecNamedCurves.GetByName("secp384r1"); ECDomainParameters ecdsa384DomainParams = new ECDomainParameters(ecdsa384X9Params.Curve, ecdsa384X9Params.G, ecdsa384X9Params.N, ecdsa384X9Params.H); ECKeyGenerationParameters ecdsa384GenParams = new ECKeyGenerationParameters(ecdsa384DomainParams, secureRandom); ECKeyPairGenerator ecdsa384Gen = new ECKeyPairGenerator(); ecdsa384Gen.Init(ecdsa384GenParams); keyPair = ecdsa384Gen.GenerateKeyPair(); var ecdsa384Key = new SshKey(SshVersion.SSH2, keyPair); ecdsa384Key.Comment = comment; return(ecdsa384Key); case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521_CERT_V1: X9ECParameters ecdsa521X9Params = SecNamedCurves.GetByName("secp521r1"); ECDomainParameters ecdsa521DomainParams = new ECDomainParameters(ecdsa521X9Params.Curve, ecdsa521X9Params.G, ecdsa521X9Params.N, ecdsa521X9Params.H); ECKeyGenerationParameters ecdsa521GenParams = new ECKeyGenerationParameters(ecdsa521DomainParams, secureRandom); ECKeyPairGenerator ecdsa521Gen = new ECKeyPairGenerator(); ecdsa521Gen.Init(ecdsa521GenParams); keyPair = ecdsa521Gen.GenerateKeyPair(); var ecdsa521Key = new SshKey(SshVersion.SSH2, keyPair); ecdsa521Key.Comment = comment; return(ecdsa521Key); case PublicKeyAlgorithm.ED25519: case PublicKeyAlgorithm.ED25519_CERT_V1: var privateKeySeed = secureRandom.GenerateSeed(Ed25519.PrivateKeySeedSizeInBytes); var publicKeyBytes = new byte[Ed25519.PublicKeySizeInBytes]; var privateKeyBytes = new byte[Ed25519.ExpandedPrivateKeySizeInBytes]; Ed25519.KeyPairFromSeed(out publicKeyBytes, out privateKeyBytes, privateKeySeed); var publicKey = new Ed25519PublicKeyParameter(publicKeyBytes); var privateKey = new Ed25519PrivateKeyParameter(privateKeyBytes); var ed25519Key = new SshKey(SshVersion.SSH2, publicKey, privateKey, comment); return(ed25519Key); default: throw new Exception("unsupported algorithm"); } }
private static AsymmetricCipherKeyPair CreateCipherKeyPair( PublicKeyAlgorithm algorithm, byte[] publicKeyBlob, byte[] privateKeyBlob) { var parser = new BlobParser(publicKeyBlob); OpensshCertificate cert; var publicKey = parser.ReadSsh2PublicKeyData(out cert); parser = new BlobParser(privateKeyBlob); switch (algorithm) { case PublicKeyAlgorithm.SSH_RSA: var rsaPublicKeyParams = (RsaKeyParameters)publicKey; var d = new BigInteger(1, parser.ReadBlob()); var p = new BigInteger(1, parser.ReadBlob()); var q = new BigInteger(1, parser.ReadBlob()); var inverseQ = new BigInteger(1, parser.ReadBlob()); /* compute missing parameters */ var dp = d.Remainder(p.Subtract(BigInteger.One)); var dq = d.Remainder(q.Subtract(BigInteger.One)); RsaPrivateCrtKeyParameters rsaPrivateKeyParams = new RsaPrivateCrtKeyParameters(rsaPublicKeyParams.Modulus, rsaPublicKeyParams.Exponent, d, p, q, dp, dq, inverseQ); return(new AsymmetricCipherKeyPair(rsaPublicKeyParams, rsaPrivateKeyParams)); case PublicKeyAlgorithm.SSH_DSS: var dsaPublicKeyParams = (DsaPublicKeyParameters)publicKey; var x = new BigInteger(1, parser.ReadBlob()); DsaPrivateKeyParameters dsaPrivateKeyParams = new DsaPrivateKeyParameters(x, dsaPublicKeyParams.Parameters); return(new AsymmetricCipherKeyPair(dsaPublicKeyParams, dsaPrivateKeyParams)); case PublicKeyAlgorithm.ED25519: var ed25596PublicKey = (Ed25519PublicKeyParameter)publicKey; byte[] privBlob = parser.ReadBlob(); byte[] privSig = new byte[64]; // OpenSSH's "private key" is actually the private key with the public key tacked on ... Array.Copy(privBlob, 0, privSig, 0, 32); Array.Copy(ed25596PublicKey.Key, 0, privSig, 32, 32); var ed25596PrivateKey = new Ed25519PrivateKeyParameter(privSig); return(new AsymmetricCipherKeyPair(ed25596PublicKey, ed25596PrivateKey)); case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384: case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521: var ecPublicKeyParams = (ECPublicKeyParameters)publicKey; var ecdsaPrivate = new BigInteger(1, parser.ReadBlob()); ECPrivateKeyParameters ecPrivateKeyParams = new ECPrivateKeyParameters(ecdsaPrivate, ecPublicKeyParams.Parameters); return(new AsymmetricCipherKeyPair(ecPublicKeyParams, ecPrivateKeyParams)); default: // unsupported encryption algorithm throw new PpkFormatterException(PpkFormatterException.PpkErrorType.PublicKeyEncryption); } }