我可以使用Bouncycastle for C#用密码创建可复制的PGP密钥对吗?

观众

编辑:此代码有效。密钥文本每次都不同,但是密钥材料相同。我更新了以下代码,以从控制台收集数据以用于密钥创建,而没有回显。

我想从带密码的livecd生成一个Pgp密钥对,分发公共密钥,并使用它来加密个人数据,然后再将其存储在Google驱动器上,但是永远不要将私钥写入磁盘。

我意识到我可以直接使用RSA密钥,但是我更喜欢使用pgp密钥,以简化易用性和灵活性。

当我需要解密数据时,我将再次从livecd启动并重现私钥。

这是我正在使用的代码...每次产生的rsa密钥都是一样的,但是pgp密钥却不同。我想念什么?

提前致谢,

代码如下:

using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Bcpg;
using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;

namespace PgpKeyFromPassphrase
{
    class Program
    {
        static void Main()
        {
            string identity = ReadIdentityFromConsole();
            DateTime keyDate = ReadDateFromConsole();
            string passPhrase = ReadPassphraseFromConsole();
            Console.WriteLine("Generating seed and keys.  This will take some time");
            //Hash the passphrasse 50,000 times
            var seed = GenerateSeed(passPhrase);
            //Create the RSA keypair from the seed
            var keys = GenerateRsaKeys(seed);
            //Create PGP secret key from keypair
            var secretKey = GeneratePgpKeys(keyDate, identity, keys);
            //Write armored secret key
            PrintSecretKey(secretKey);
            //Write armored public key
            PrintPublicKey(secretKey);
            Console.WriteLine("Copy the key and press enter to exit the program");
            Console.ReadLine();
        }


        private static string ReadIdentityFromConsole()
        {
            string retVal = null;
            while (retVal == null || retVal.Equals(string.Empty))
            {
                Console.WriteLine("Type a name to be associated with the Key");
                retVal = Console.ReadLine();
            }
            return retVal;
        }

        private static DateTime ReadDateFromConsole()
        {
            DateTime retVal = DateTime.Today;
            while (true)
            {
                Console.WriteLine("Enter the key creation date.  Press enter for today");
                var line = Console.ReadLine();
                if (line == null || line.Equals(string.Empty) || DateTime.TryParse(line, out retVal)) break;
                else Console.WriteLine("Failed to parse date, try again");
            }
            return retVal;
        }

        static string ReadPassphraseFromConsole()
        {
            var pass1 = new StringBuilder();
            var pass2 = new StringBuilder();
            while (pass1.Length == 0 || !pass1.Equals(pass2))
            {
                if (pass1.Length > 0 && pass2.Length > 0 && !pass1.Equals(pass2))
                {
                    pass1 = new StringBuilder();
                    pass2 = new StringBuilder();
                    Console.WriteLine("Passphrases don't match! Try again.");
                }
                Console.WriteLine("type a strong passphrase and hit enter");
                var key = Console.ReadKey(true);
                while (!key.Key.Equals(ConsoleKey.Enter))
                {
                    if (key.Key.Equals(ConsoleKey.Backspace))
                    {
                        if (pass1.Length > 0) pass1.Remove(pass1.Length - 1, 1);
                    }
                    else pass1.Append(key.KeyChar);
                    key = Console.ReadKey(true);
                }
                Console.WriteLine("repeat passphrase and hit enter");
                key = Console.ReadKey(true);
                while (!key.Key.Equals(ConsoleKey.Enter))
                {
                    if (key.Key.Equals(ConsoleKey.Backspace))
                    {
                        if (pass2.Length > 0) pass2.Remove(pass2.Length - 1, 1);
                    }
                    else pass2.Append(key.KeyChar);
                    key = Console.ReadKey(true);
                }
            }
            return pass1.ToString();
        }

        static byte[] GenerateSeed(string passPhrase)
        {
            //Hash the passphrasse 50,000 times
            var passPhraseBytes = new byte[passPhrase.Length * sizeof(char)];
            Buffer.BlockCopy(passPhrase.ToCharArray(), 0, passPhraseBytes, 0, passPhraseBytes.Length);
            var digester = new Sha256Digest();
            var seed = new byte[digester.GetDigestSize()];
            digester.BlockUpdate(seed, 0, seed.Length);
            digester.DoFinal(seed, 0);
            for (var i = 0; i < 49999; i++)
            {
                digester = new Sha256Digest();
                digester.BlockUpdate(seed, 0, seed.Length);
                digester.DoFinal(seed, 0);
            }
            return seed;
        }

        static AsymmetricCipherKeyPair GenerateRsaKeys(byte[] seed)
        {
            var kpg = new RsaKeyPairGenerator();
            kpg.Init(new RsaKeyGenerationParameters(BigInteger.ValueOf(0x13), new SecureRandom(seed), 4096, 8));
            AsymmetricCipherKeyPair keys = kpg.GenerateKeyPair();
            return keys;
        }

        static PgpSecretKey GeneratePgpKeys(DateTime keyDate, string identity, AsymmetricCipherKeyPair keys)
        {
            var secretKey = new PgpSecretKey(PgpSignature.DefaultCertification, PublicKeyAlgorithmTag.RsaGeneral, keys.Public, keys.Private, keyDate, identity, SymmetricKeyAlgorithmTag.Cast5, null, null, null, new SecureRandom());
            return secretKey;
        }

        static void PrintSecretKey(PgpSecretKey secretKey)
        {
            var secretMemStream = new MemoryStream();
            var secretArmoredStream = new ArmoredOutputStream(secretMemStream);
            secretKey.Encode(secretArmoredStream);
            secretArmoredStream.Close();
            var ascPgpSecretKey = Encoding.ASCII.GetString(secretMemStream.ToArray());
            Console.WriteLine(ascPgpSecretKey);
        }

        static void PrintPublicKey(PgpSecretKey secretKey)
        {
            var pubMemStream = new MemoryStream();
            var pubArmoredStream = new ArmoredOutputStream(pubMemStream);
            secretKey.PublicKey.Encode(pubArmoredStream);
            pubArmoredStream.Close();
            var ascPgpPublicKey = Encoding.ASCII.GetString(pubMemStream.ToArray());
            Console.WriteLine(ascPgpPublicKey);
        }

    }
}
观众

谢谢邓肯!

有效。

即使基础RSA密钥相同,PGP密钥输出的ASCII装甲文本也每次都不相同。

但是,我能够使用公共密钥生成一个密钥对来加密文件,然后生成一个新的密钥对并使用该新的私有密钥来解密文件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我可以使用kwallet管理PGP密钥吗?

来自分类Dev

我可以使用Openssl创建DKIM密钥吗

来自分类Dev

我可以使用Terraform创建GCP API密钥吗?

来自分类Dev

我可以使用python CSP吗?

来自分类Dev

我可以使用迭代器吗?

来自分类Dev

我可以使用通配符替换吗

来自分类Dev

我可以使用RTF格式吗?

来自分类Dev

骨骼可以使用我的插件吗?

来自分类Dev

Filezilla:我可以使用OpenSSH格式密钥吗?

来自分类Dev

我可以使用密码保护NFS共享吗?

来自分类Dev

我可以使用assign复制对象的对象吗?

来自分类Dev

我可以使用Linq为C#排序字典创建比较器吗

来自分类Dev

我可以使用LinqPad创建的DbContext吗?

来自分类Dev

我可以使用MySQL Workbench创建MariaDB吗?

来自分类Dev

我可以使用lxml创建此XML文件吗?

来自分类Dev

我可以使用FactoryGirl创建无效值吗?

来自分类Dev

我可以使用内联操作按钮创建DataTable吗?

来自分类Dev

我可以使用简单的Int创建结构的实例吗?

来自分类Dev

我可以使用标准JavaScript函数创建XMLHttpRequest吗?

来自分类Dev

我可以使用flutter在Firestore上创建索引吗?

来自分类Dev

我可以使用SVG创建书法外观吗?

来自分类Dev

我可以使用MySQL Workbench创建数据吗?

来自分类Dev

我可以使用PhoneGap创建和提交iBook吗

来自分类Dev

我可以使用“相对”变量创建HashMap吗?

来自分类Dev

我可以使用Object.assign创建“类”吗

来自分类Dev

我可以使用ReactTransitionGroup在更新时创建过渡吗?

来自分类Dev

我可以使用 Flexbox 创建背景和前景吗?

来自分类Dev

我可以使用 '?P=pagename' 创建 PHP 页面吗?

来自分类Dev

我可以使用尝试,用资源与已创建的InputStream?

Related 相关文章

热门标签

归档