/// <summary>
        /// Create master signing key.
        /// </summary>
        /// <param name="keyRingGen">
        /// Key ring generator.
        /// </param>
        /// <param name="identity">
        /// Identity of the key.
        /// </param>
        /// <param name="password">
        /// Password to protect the secret key.
        /// </param>
        /// <param name="expires">
        /// Key expiry; null means never expires.
        /// </param>
        /// <param name="encryptKeyLength">
        /// Length of the encryption key.
        /// </param>
        /// <param name="encryptGenerator">
        /// Generator for the encryption key.
        /// </param>
        /// <param name="encryptionAlgorithm">
        /// Encryption algorithm.
        /// </param>
        /// <param name="symmetricAlgorithm">
        /// Symmetric algorithm.
        /// </param>
        /// <returns>
        /// Returns the <see cref="PgpKeyRingGenerator"/> with the keyring properties
        /// thus far.
        /// </returns>
        public static PgpKeyRingGenerator CreateEncryptionSubkey(
            PgpKeyRingGenerator keyRingGen,
            string identity,
            string password,
            DateTime?expires,
            int encryptKeyLength    = 2048,
            string encryptGenerator = "RSA",
            PublicKeyAlgorithmTag encryptionAlgorithm   = PublicKeyAlgorithmTag.RsaEncrypt,
            SymmetricKeyAlgorithmTag symmetricAlgorithm = SymmetricKeyAlgorithmTag.Aes256)
        {
            var keyringParameters = new KeyRingParameters(encryptKeyLength, encryptGenerator)
            {
                Password = password,
                Identity = identity,
                PrivateKeyEncryptionAlgorithm = symmetricAlgorithm,
                SymmetricAlgorithms           = new[]
                {
                    SymmetricKeyAlgorithmTag.Aes256,
                    SymmetricKeyAlgorithmTag.Aes192,
                    SymmetricKeyAlgorithmTag.Aes128
                },
                HashAlgorithms = new[]
                {
                    HashAlgorithmTag.Sha256,
                    HashAlgorithmTag.Sha1,
                    HashAlgorithmTag.Sha384,
                    HashAlgorithmTag.Sha512,
                    HashAlgorithmTag.Sha224,
                }
            };

            // encryption key
            var generator = GeneratorUtilities.GetKeyPairGenerator(encryptGenerator);

            generator.Init(keyringParameters.KeyParams);
            var encKeyPair = new PgpKeyPair(encryptionAlgorithm, generator.GenerateKeyPair(), DateTime.UtcNow);

            var symmetricAlgorithms = (from a in keyringParameters.SymmetricAlgorithms
                                       select(int) a).ToArray();
            var hashAlgorithms = (from a in keyringParameters.HashAlgorithms
                                  select(int) a).ToArray();

            Debug.WriteLine("Generated encryption key with ID " + encKeyPair.KeyId.ToString("X"));
            var encSubpckGen = new PgpSignatureSubpacketGenerator();

            encSubpckGen.SetKeyFlags(false, PgpKeyFlags.CanEncryptCommunications | PgpKeyFlags.CanEncryptStorage);
            encSubpckGen.SetPreferredSymmetricAlgorithms(false, symmetricAlgorithms);
            encSubpckGen.SetPreferredHashAlgorithms(false, hashAlgorithms);
            if (expires != null)
            {
                encSubpckGen.SetKeyExpirationTime(false, (long)((DateTime)expires - DateTime.Now).TotalSeconds);
            }

            // add encryption subkey to keyring
            keyRingGen.AddSubKey(encKeyPair, encSubpckGen.Generate(), null);
            return(keyRingGen);
        }
        /// <summary>
        /// Get parameters for the specified public key algorithm.
        /// </summary>
        /// <param name="username">
        /// The username of the key.
        /// </param>
        /// <param name="password">
        /// The password for the private key.
        /// </param>
        /// <param name="keyLength">
        /// The key length.
        /// </param>
        /// <param name="symmetricKeyAlgorithm">
        /// The symmetric key algorithm.
        /// </param>
        /// <param name="publicKeyAlgorithm">
        /// The public key algorithm.
        /// </param>
        /// <returns>
        /// The generated <see cref="KeyRingParameters"/>.
        /// </returns>
        /// <exception cref="NotSupportedException">
        /// Thrown if the <see cref="PublicKeyAlgorithmTag"/> is not supported.
        /// </exception>
        private static KeyRingParameters GetParametersForPublicKeyAlgorithm(
            string username,
            string password,
            int keyLength,
            SymmetricKeyAlgorithmTag symmetricKeyAlgorithm,
            PublicKeyAlgorithmTag publicKeyAlgorithm)
        {
            string generatorIndicator;

            if (publicKeyAlgorithm.ToString().StartsWith("rsa", StringComparison.CurrentCultureIgnoreCase))
            {
                generatorIndicator = "RSA";
            }
            else if (publicKeyAlgorithm.ToString().StartsWith("dsa", StringComparison.CurrentCultureIgnoreCase))
            {
                generatorIndicator = "DSA";
            }
            else if (publicKeyAlgorithm.ToString().StartsWith("elg", StringComparison.CurrentCultureIgnoreCase))
            {
                generatorIndicator = "ELGAMAL";
            }
            else
            {
                throw new NotSupportedException($"Public key algorithm not supported: {publicKeyAlgorithm.ToString()}");
            }

            var keyringParameters = new KeyRingParameters(keyLength, generatorIndicator)
            {
                Password = password,
                Identity = username,
                PrivateKeyEncryptionAlgorithm = symmetricKeyAlgorithm,
                SymmetricAlgorithms           = new[]
                {
                    SymmetricKeyAlgorithmTag.Aes256,
                    SymmetricKeyAlgorithmTag.Aes192,
                    SymmetricKeyAlgorithmTag.Aes128
                },
                HashAlgorithms = new[]
                {
                    HashAlgorithmTag.Sha256,
                    HashAlgorithmTag.Sha1,
                    HashAlgorithmTag.Sha384,
                    HashAlgorithmTag.Sha512,
                    HashAlgorithmTag.Sha224,
                }
            };

            return(keyringParameters);
        }
        /// <summary>
        /// Create master signing key.
        /// </summary>
        /// <param name="identity">
        /// Identity of the key.
        /// </param>
        /// <param name="password">
        /// Password to protect the secret key.
        /// </param>
        /// <param name="expires">
        /// Key expiry; null means never expires.
        /// </param>
        /// <param name="signKeyLength">
        /// Length of the signing key.
        /// </param>
        /// <param name="signGenerator">
        /// Generator for the signing key.
        /// </param>
        /// <param name="signingAlgorithm">
        /// Signing algorithm.
        /// </param>
        /// <param name="symmetricAlgorithm">
        /// Symmetric algorithm.
        /// </param>
        /// <returns>
        /// Returns the <see cref="PgpKeyRingGenerator"/> with the keyring properties
        /// thus far.
        /// </returns>
        public static PgpKeyRingGenerator CreateMasterSigningKey(
            string identity,
            string password,
            DateTime?expires,
            int signKeyLength    = 2048,
            string signGenerator = "RSA",
            PublicKeyAlgorithmTag signingAlgorithm      = PublicKeyAlgorithmTag.RsaSign,
            SymmetricKeyAlgorithmTag symmetricAlgorithm = SymmetricKeyAlgorithmTag.Aes256)
        {
            var keyringParameters = new KeyRingParameters(signKeyLength, signGenerator)
            {
                Password = password,
                Identity = identity,
                PrivateKeyEncryptionAlgorithm = symmetricAlgorithm,
                SymmetricAlgorithms           = new[]
                {
                    SymmetricKeyAlgorithmTag.Aes256,
                    SymmetricKeyAlgorithmTag.Aes192,
                    SymmetricKeyAlgorithmTag.Aes128
                },
                HashAlgorithms = new[]
                {
                    HashAlgorithmTag.Sha256,
                    HashAlgorithmTag.Sha1,
                    HashAlgorithmTag.Sha384,
                    HashAlgorithmTag.Sha512,
                    HashAlgorithmTag.Sha224,
                }
            };

            // master signing key
            var generator = GeneratorUtilities.GetKeyPairGenerator(signGenerator);

            generator.Init(keyringParameters.KeyParams);
            var masterKeyPair = new PgpKeyPair(signingAlgorithm, generator.GenerateKeyPair(), DateTime.UtcNow);

            Debug.WriteLine("Generated master key with ID " + masterKeyPair.KeyId.ToString("X"));

            var symmetricAlgorithms = (from a in keyringParameters.SymmetricAlgorithms
                                       select(int) a).ToArray();
            var hashAlgorithms = (from a in keyringParameters.HashAlgorithms
                                  select(int) a).ToArray();

            var masterSubpckGen = new PgpSignatureSubpacketGenerator();

            masterSubpckGen.SetKeyFlags(false, PgpKeyFlags.CanSign | PgpKeyFlags.CanCertify);
            masterSubpckGen.SetPreferredSymmetricAlgorithms(false, symmetricAlgorithms);
            masterSubpckGen.SetPreferredHashAlgorithms(false, hashAlgorithms);
            if (expires != null)
            {
                masterSubpckGen.SetKeyExpirationTime(false, (long)((DateTime)expires - DateTime.Now).TotalSeconds);
            }

            // keyring -- adding master key
            return(new PgpKeyRingGenerator(
                       PgpSignature.DefaultCertification,
                       masterKeyPair,
                       keyringParameters.Identity,
                       keyringParameters.PrivateKeyEncryptionAlgorithm,
                       keyringParameters.GetPassword(),
                       true,
                       masterSubpckGen.Generate(),
                       null,
                       new SecureRandom()));
        }