public void Init(bool forSigning, ICipherParameters parameters) { if (parameters == null) { throw new ArgumentNullException("parameters"); } message.Clear(); if (forSigning) { privateKey = parameters as Ed25519PrivateKeyParameter; publicKey = null; if (privateKey == null) { throw new ArgumentException("Expecting Ed25519PrivateKeyParameter", "parameters"); } } else { publicKey = parameters as Ed25519PublicKeyParameter; privateKey = null; if (publicKey == null) { throw new ArgumentException("Expecting Ed25519PublicKeyParameter", "parameters"); } } }
/// <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"); } }
private static AsymmetricCipherKeyPair CreateCipherKeyPair( PublicKeyAlgorithm algorithm, byte[] publicKeyBlob, byte[] privateKeyBlob) { var parser = new BlobParser(publicKeyBlob); var publicKey = parser.ReadSsh2PublicKeyData(); 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); } }
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: KeyGenerationParameters keyGenParam = new KeyGenerationParameters(secureRandom, 512); RsaKeyPairGenerator rsaKeyPairGen = new RsaKeyPairGenerator(); rsaKeyPairGen.Init(keyGenParam); AsymmetricCipherKeyPair keyPair = rsaKeyPairGen.GenerateKeyPair(); var rsaKey = new SshKey(version, keyPair); rsaKey.Comment = comment; return rsaKey; case PublicKeyAlgorithm.SSH_DSS: 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: 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: 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: 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: 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"); } }