Exemple #1
0
        } // End Function VerifySignature

        // https://stackoverflow.com/questions/18244630/elliptic-curve-with-digital-signature-algorithm-ecdsa-implementation-on-bouncy
        public static Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair GenerateEcdsaKeyPair()
        {
            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator gen =
                new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();

            Org.BouncyCastle.Security.SecureRandom secureRandom =
                new Org.BouncyCastle.Security.SecureRandom();

            // https://github.com/bcgit/bc-csharp/blob/master/crypto/src/asn1/sec/SECNamedCurves.cs#LC1096
            Org.BouncyCastle.Asn1.X9.X9ECParameters ps =
                Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");

            Org.BouncyCastle.Crypto.Parameters.ECDomainParameters ecParams =
                new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(ps.Curve, ps.G, ps.N, ps.H);

            Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters keyGenParam =
                new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(ecParams, secureRandom);

            gen.Init(keyGenParam);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair kp = gen.GenerateKeyPair();

            // Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters priv =
            //     (Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters)kp.Private;

            return(kp);
        } // End Function GenerateEcdsaKeyPair
        public ECDiffieHellmanBc(Int32 keySize)
        {
            Org.BouncyCastle.Asn1.X9.X9ECParameters ecParams;
            switch (keySize) {
            case 256:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256r1");
                break;
            case 384:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp384r1");
                break;
            case 521:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp521r1");
                break;
            default:
                throw new ArgumentException("ECDiffieHellman key size " + keySize + " not supported");
            }
            _keySize = keySize;
            _domainParameters = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed());

            // Initialize key generation parameters with new SecureRandom
            Org.BouncyCastle.Security.SecureRandom secureRandom = new Org.BouncyCastle.Security.SecureRandom();
            ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(_domainParameters, secureRandom);

            // Generate key pair from domain parameters
            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator generator = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
            generator.Init(keyGenParams);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();

            // Save the private and public key parameters
            _privateKeyParameters = (ECPrivateKeyParameters) keyPair.Private;
            _publicKeyParameters = (ECPublicKeyParameters) keyPair.Public;

            _kdf = ECDiffieHellmanKeyDerivationFunction.Hash;
            _hashAlgorithm = CngAlgorithm.Sha256;
        }
Exemple #3
0
        public static PkiKeyPair GenerateEcdsaKeyPair(int bits, int hashBits = -1)
        {
            // Based on:
            //    https://github.com/bcgit/bc-csharp/blob/master/crypto/test/src/crypto/test/ECTest.cs#L331
            //    https://www.codeproject.com/Tips/1150485/Csharp-Elliptical-Curve-Cryptography-with-Bouncy-C

            // This produced the following error against Let's Encrypt CA:
            //    ACMESharp.Protocol.AcmeProtocolException : Error parsing certificate request: asn1: structure error: tags don't match (6 vs {class:0 tag:16 length:247 isCompound:true}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} ObjectIdentifier @3

            // var ecNistParams = NistNamedCurves.GetByName("P-" + bits);
            // var ecDomainParams = new ECDomainParameters(ecNistParams.Curve,
            //         ecNistParams.G, ecNistParams.N, ecNistParams.H, ecNistParams.GetSeed());
            // var ecParams = new ECKeyGenerationParameters(ecDomainParams, new SecureRandom());

            // So according to [this](https://github.com/golang/go/issues/18634#issuecomment-272527314)
            // it seems we were passing in arbitrary curve details instead of a named curve OID as we do here:

            var ecCurveOid = NistNamedCurves.GetOid("P-" + bits);;
            var ecParams   = new ECKeyGenerationParameters(ecCurveOid, new SecureRandom());
            var ecKpGen    = GeneratorUtilities.GetKeyPairGenerator("ECDSA");

            ecKpGen.Init(ecParams);
            var nativeKeyPair = ecKpGen.GenerateKeyPair();

            var kpg = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();

            kpg.Init(ecParams);

            // SHA + ECDSA algor selection based on:
            //    https://github.com/bcgit/bc-csharp/blob/master/crypto/src/security/SignerUtilities.cs
            // Transcode Length:
            //    * lengths are specified as in:
            //       https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-24#section-3.4
            //    * see explanation in the docs for "TranscodeSignatureToConcat" for what this is all about
            var transcodeLength = 0;

            if (hashBits == -1)
            {
                switch (bits)
                {
                case 521: hashBits = 512; transcodeLength = 132; break;

                case 384: hashBits = 384; transcodeLength = 96; break;

                default: hashBits = 256; transcodeLength = 64; break;
                }
            }
            var sigAlgor = $"SHA{hashBits}WITHECDSA";

            return(new PkiKeyPair(nativeKeyPair, PkiAsymmetricAlgorithm.Ecdsa,
                                  (prv, data) => Sign(sigAlgor, prv, data, transcodeLength),
                                  (pub, data, sig) => Verify(sigAlgor, pub, data, sig),
                                  (keys, prv) => ExportEcJwk(bits, keys, prv)));
        }
Exemple #4
0
        GenerateGost3410KeyPair(Org.BouncyCastle.Security.SecureRandom random, int keystrength)
        {
            Org.BouncyCastle.Crypto.Parameters.ECDomainParameters gostEcDomainParameters =
                Org.BouncyCastle.Asn1.CryptoPro.ECGost3410NamedCurves.GetByOid(
                    Org.BouncyCastle.Asn1.CryptoPro.CryptoProObjectIdentifiers.GostR3410x2001CryptoProA);

            Org.BouncyCastle.Crypto.IAsymmetricCipherKeyPairGenerator gostKeyGen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
            Org.BouncyCastle.Crypto.KeyGenerationParameters           genParam   = new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(gostEcDomainParameters, random);
            gostKeyGen.Init(genParam);

            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair kp = gostKeyGen.GenerateKeyPair();
            return(kp);
        }
Exemple #5
0
        public static System.Security.Cryptography.ECDsa GetMsEcdsaProvider()
        {
            string namedCurve = "prime256v1";

            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator pGen =
                new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();

            Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters genParam =
                new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(
                    Org.BouncyCastle.Asn1.X9.X962NamedCurves.GetOid(namedCurve),
                    new Org.BouncyCastle.Security.SecureRandom()
                    );

            pGen.Init(genParam);

            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair = pGen.GenerateKeyPair();

            Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters pub =
                (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)keyPair.Public;

            Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters priv =
                (Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters)keyPair.Private;


            System.Security.Cryptography.ECParameters pars = new ECParameters();
            //string str = priv.Parameters.Curve.ToString();
            //System.Console.WriteLine(str);

            //pars.Curve = new ECCurve();


            //pars.D = priv.D.ToByteArray();
            //pars.Q = new System.Security.Cryptography.ECPoint();
            //pars.Q.X = pub.Q.X.GetEncoded();
            //pars.Q.Y = pub.Q.Y.GetEncoded();

            //System.Security.Cryptography.ECDsa.Create(pars);


            // The CngKey can be created by importing the key using the Der encoded bytes:
            Org.BouncyCastle.Asn1.Pkcs.PrivateKeyInfo bcKeyInfo =
                Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private)
            ;

            byte[] pkcs8Blob   = bcKeyInfo.GetDerEncoded();
            CngKey importedKey = CngKey.Import(pkcs8Blob, CngKeyBlobFormat.Pkcs8PrivateBlob);

            return(new System.Security.Cryptography.ECDsaCng(importedKey));
        }
        public void CompareSecp256k1KeyGenerationRuntimes()
        {
            int num_runs = 100;

            long openecc_time_sum = 0L;
            long bc_time_sum = 0L;

            for (int i = 0; i < num_runs; i++)
            {
                ///
                /// OpenECC
                ///
                var openecc_curve = CurveFactory.secp256k1;

                var openecc_keygen_timer = Stopwatch.StartNew();

                var openecc_encoder = new ProbabilisticWeierstrassMessageEncoder(openecc_curve, new BigInteger(7));
                var openecc_encryptor = new ElGamalEncryptor(openecc_curve, openecc_encoder);
                var openecc_keys = openecc_encryptor.GenerateKeyPair();

                openecc_keygen_timer.Stop();
                openecc_time_sum += openecc_keygen_timer.Elapsed.Milliseconds;
            }

            for (int i = 0; i < num_runs; i++)
            {
                ///
                ///Bouncy Castle
                ///
                var bc_stuff = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");

                var bc_keygen_timer = Stopwatch.StartNew();

                var bc_keygen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
                var bc_domain_params = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(bc_stuff.Curve, bc_stuff.G, bc_stuff.N);
                var bc_random = new Org.BouncyCastle.Security.SecureRandom();
                var bc_keygen_params = new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(bc_domain_params, bc_random);
                bc_keygen.Init(bc_keygen_params);
                var bc_keys = bc_keygen.GenerateKeyPair();

                bc_keygen_timer.Stop();
                bc_time_sum += bc_keygen_timer.Elapsed.Milliseconds;
            }

            throw new NotImplementedException("BC: " + (bc_time_sum/(double)num_runs) + "; OpenECC: " + (openecc_time_sum/(double)num_runs));
            //RuntimeAssert.LessThan(bc_time_sum / (double)num_runs, openecc_time_sum / (double)num_runs);
        }
        } // End Function GenerateDHKeyPair

        public static Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair GenerateEcKeyPair(
            Org.BouncyCastle.Asn1.X9.X9ECParameters ecParam
            , Org.BouncyCastle.Security.SecureRandom secureRandom
            )
        {
            Org.BouncyCastle.Crypto.Parameters.ECDomainParameters ecDomain =
                new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(ecParam.Curve, ecParam.G, ecParam.N);

            Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters keygenParam =
                new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(ecDomain, secureRandom);

            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator keyGenerator =
                new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();

            keyGenerator.Init(keygenParam);
            return(keyGenerator.GenerateKeyPair());
        } // End Function GenerateEcKeyPair
        public ECDiffieHellmanBc(Int32 keySize)
        {
            Org.BouncyCastle.Asn1.X9.X9ECParameters ecParams;
            switch (keySize)
            {
            case 256:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256r1");
                break;

            case 384:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp384r1");
                break;

            case 521:
                ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp521r1");
                break;

            default:
                throw new ArgumentException("ECDiffieHellman key size " + keySize + " not supported");
            }
            _keySize          = keySize;
            _domainParameters = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed());

            // Initialize key generation parameters with new SecureRandom
            Org.BouncyCastle.Security.SecureRandom secureRandom = new Org.BouncyCastle.Security.SecureRandom();
            ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(_domainParameters, secureRandom);

            // Generate key pair from domain parameters
            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator generator = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
            generator.Init(keyGenParams);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair();

            // Save the private and public key parameters
            _privateKeyParameters = (ECPrivateKeyParameters)keyPair.Private;
            _publicKeyParameters  = (ECPublicKeyParameters)keyPair.Public;

            _kdf           = ECDiffieHellmanKeyDerivationFunction.Hash;
            _hashAlgorithm = CngAlgorithm.Sha256;
        }
        } // End Function GenerateEcKeyPair

        public static Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair GenerateGostKeyPair(string curveName, Org.BouncyCastle.Security.SecureRandom random)
        {
            Org.BouncyCastle.Asn1.X9.X9ECParameters ecParam = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName(curveName);

            if (ecParam == null)
            {
                ecParam = Org.BouncyCastle.Crypto.EC.CustomNamedCurves.GetByName(curveName);
            }


            Org.BouncyCastle.Crypto.Parameters.ECDomainParameters        parameters = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(ecParam);
            Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters keyGenerationParameters = new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(parameters, random);

            Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator keygenerator = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator("ECGOST3410");
            keygenerator.Init(keyGenerationParameters);
            Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair pair = keygenerator.GenerateKeyPair();

            // Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters validatorPrivate = (Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters)pair.Private;
            // Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters validatorPublic = (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)pair.Public;

            return(pair);
        } // End Function GenerateGostKeyPair
Exemple #10
0
        /// <summary>
        ///   Creates a new signing key pair
        /// </summary>
        /// <param name="name">The name of the key or zone</param>
        /// <param name="recordClass">The record class of the DnsKeyRecord</param>
        /// <param name="timeToLive">The TTL in seconds to the DnsKeyRecord</param>
        /// <param name="flags">The Flags of the DnsKeyRecord</param>
        /// <param name="protocol">The protocol version</param>
        /// <param name="algorithm">The key algorithm</param>
        /// <param name="keyStrength">The key strength or 0 for default strength</param>
        /// <returns></returns>
        public static KeyPairRecord CreateSigningKey(DnsSecAlgorithm algorithm, DnsKeyFlags flags, int keyStrength = 0)
        {
            // Found in DnsKeyRecord.CreateSigningKey
            KeyPairRecord rec = new KeyPairRecord();

            rec.Flags     = flags;
            rec.Algorithm = algorithm;

            Org.BouncyCastle.Security.SecureRandom _secureRandom =
                new Org.BouncyCastle.Security.SecureRandom(new Org.BouncyCastle.Crypto.Prng.CryptoApiRandomGenerator());

            // https://csharp.hotexamples.com/examples/Org.BouncyCastle.Crypto.Generators/DsaKeyPairGenerator/GenerateKeyPair/php-dsakeypairgenerator-generatekeypair-method-examples.html

            switch (algorithm)
            {
            case DnsSecAlgorithm.RsaSha1:
            case DnsSecAlgorithm.RsaSha1Nsec3Sha1:
            case DnsSecAlgorithm.RsaSha256:
            case DnsSecAlgorithm.RsaSha512:
                if (keyStrength == 0)
                {
                    keyStrength = (flags == (DnsKeyFlags.Zone | DnsKeyFlags.SecureEntryPoint)) ? 2048 : 1024;
                }

                Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator rsaKeyGen = new Org.BouncyCastle.Crypto.Generators.RsaKeyPairGenerator();
                rsaKeyGen.Init(new Org.BouncyCastle.Crypto.KeyGenerationParameters(_secureRandom, keyStrength));
                var rsaKey = rsaKeyGen.GenerateKeyPair();
                rec.KeyPair    = rsaKey;
                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaKey.Private).GetDerEncoded();
                var rsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)rsaKey.Public;
                var rsaExponent  = rsaPublicKey.Exponent.ToByteArrayUnsigned();
                var rsaModulus   = rsaPublicKey.Modulus.ToByteArrayUnsigned();

                int offset = 1;
                if (rsaExponent.Length > 255)
                {
                    rec.PublicKey = new byte[3 + rsaExponent.Length + rsaModulus.Length];
                    EncodeUShort(rec.PublicKey, ref offset, (ushort)rec.PublicKey.Length);
                }
                else
                {
                    rec.PublicKey    = new byte[1 + rsaExponent.Length + rsaModulus.Length];
                    rec.PublicKey[0] = (byte)rsaExponent.Length;
                }
                EncodeByteArray(rec.PublicKey, ref offset, rsaExponent);
                EncodeByteArray(rec.PublicKey, ref offset, rsaModulus);
                break;

            case DnsSecAlgorithm.Dsa:
            case DnsSecAlgorithm.DsaNsec3Sha1:
                if (keyStrength == 0)
                {
                    keyStrength = 1024;
                }

                Org.BouncyCastle.Crypto.Generators.DsaParametersGenerator dsaParamsGen = new Org.BouncyCastle.Crypto.Generators.DsaParametersGenerator();
                dsaParamsGen.Init(keyStrength, 12, _secureRandom);
                Org.BouncyCastle.Crypto.Generators.DsaKeyPairGenerator dsaKeyGen = new Org.BouncyCastle.Crypto.Generators.DsaKeyPairGenerator();
                dsaKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.DsaKeyGenerationParameters(_secureRandom, dsaParamsGen.GenerateParameters()));
                Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair dsaKey = dsaKeyGen.GenerateKeyPair();
                rec.KeyPair = dsaKey;

                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(dsaKey.Private).GetDerEncoded();
                var dsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.DsaPublicKeyParameters)dsaKey.Public;

                byte[] dsaY = dsaPublicKey.Y.ToByteArrayUnsigned();
                byte[] dsaP = dsaPublicKey.Parameters.P.ToByteArrayUnsigned();
                byte[] dsaQ = dsaPublicKey.Parameters.Q.ToByteArrayUnsigned();
                byte[] dsaG = dsaPublicKey.Parameters.G.ToByteArrayUnsigned();
                byte   dsaT = (byte)((dsaY.Length - 64) / 8);

                rec.PublicKey    = new byte[21 + 3 * dsaY.Length];
                rec.PublicKey[0] = dsaT;
                dsaQ.CopyTo(rec.PublicKey, 1);
                dsaP.CopyTo(rec.PublicKey, 21);
                dsaG.CopyTo(rec.PublicKey, 21 + dsaY.Length);
                dsaY.CopyTo(rec.PublicKey, 21 + 2 * dsaY.Length);
                break;

            case DnsSecAlgorithm.EccGost:
                Org.BouncyCastle.Crypto.Parameters.ECDomainParameters gostEcDomainParameters = Org.BouncyCastle.Asn1.CryptoPro.ECGost3410NamedCurves.GetByOid(Org.BouncyCastle.Asn1.CryptoPro.CryptoProObjectIdentifiers.GostR3410x2001CryptoProA);

                var gostKeyGen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
                gostKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(gostEcDomainParameters, _secureRandom));

                var gostKey = gostKeyGen.GenerateKeyPair();
                rec.KeyPair    = gostKey;
                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(gostKey.Private).GetDerEncoded();
                var gostPublicKey = (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)gostKey.Public;

                rec.PublicKey = new byte[64];

                // gostPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 32);
                gostPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 32);
                // gostPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);
                gostPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 0);

                System.Array.Reverse(rec.PublicKey);
                break;

            case DnsSecAlgorithm.EcDsaP256Sha256:
            case DnsSecAlgorithm.EcDsaP384Sha384:
                int ecDsaDigestSize;
                Org.BouncyCastle.Asn1.X9.X9ECParameters ecDsaCurveParameter;

                if (algorithm == DnsSecAlgorithm.EcDsaP256Sha256)
                {
                    ecDsaDigestSize     = new Org.BouncyCastle.Crypto.Digests.Sha256Digest().GetDigestSize();
                    ecDsaCurveParameter = Org.BouncyCastle.Asn1.Nist.NistNamedCurves.GetByOid(Org.BouncyCastle.Asn1.Sec.SecObjectIdentifiers.SecP256r1);
                }
                else
                {
                    ecDsaDigestSize     = new Org.BouncyCastle.Crypto.Digests.Sha384Digest().GetDigestSize();
                    ecDsaCurveParameter = Org.BouncyCastle.Asn1.Nist.NistNamedCurves.GetByOid(Org.BouncyCastle.Asn1.Sec.SecObjectIdentifiers.SecP384r1);
                }

                Org.BouncyCastle.Crypto.Parameters.ECDomainParameters ecDsaP384EcDomainParameters = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(
                    ecDsaCurveParameter.Curve,
                    ecDsaCurveParameter.G,
                    ecDsaCurveParameter.N,
                    ecDsaCurveParameter.H,
                    ecDsaCurveParameter.GetSeed());

                var ecDsaKeyGen = new Org.BouncyCastle.Crypto.Generators.ECKeyPairGenerator();
                ecDsaKeyGen.Init(new Org.BouncyCastle.Crypto.Parameters.ECKeyGenerationParameters(ecDsaP384EcDomainParameters, _secureRandom));

                Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair ecDsaKey = ecDsaKeyGen.GenerateKeyPair();
                rec.KeyPair = ecDsaKey;

                rec.PrivateKey = Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecDsaKey.Private).GetDerEncoded();
                var ecDsaPublicKey = (Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters)ecDsaKey.Public;

                rec.PublicKey = new byte[ecDsaDigestSize * 2];
                // ecDsaPublicKey.Q.X.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0);
                ecDsaPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, 0);
                // ecDsaPublicKey.Q.Y.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, ecDsaDigestSize);
                ecDsaPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(rec.PublicKey, ecDsaDigestSize);
                break;

            default:
                throw new System.NotSupportedException();
            }

            // return new DnsKeyRecord(name, recordClass, timeToLive, flags, protocol, algorithm, rec.PublicKey, rec.PrivateKey);
            return(rec);
        }