I would like to generate a Pgp keypair from a livecd with a pass
phrase, distribute the public key and use it to encrypt personal data
before I store it at Google drive, but never write the private key to
disk.

I realize I could just use the RSA key directly, but I would prefer to
have a pgp key for ease of use and flexibility.

When I need to decrypt data I would boot from a livecd again and
reproduce the private key.

This is the code I am using... It produces the rsa key the same every
time, but the pgp keys come out different.  What am I missing.

Thanks in advance,


CODE:

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;
using Org.BouncyCastle.OpenSsl;

namespace PgpKeyFromPassphrase
{
    class Program
    {
        static void Main(string[] args)
        {
            var passPhrase = args[0]; // a very long passphrase with
nonsense words
            var keyDate = new DateTime(2014, 1, 1);
            var identity = "My Name";

            //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);
            }

            //Create the RSA keypair from the seed
            IAsymmetricCipherKeyPairGenerator kpg = new RsaKeyPairGenerator();
            kpg.Init(new
RsaKeyGenerationParameters(BigInteger.ValueOf(0x13), new
SecureRandom(seed), 4096, 8));
            AsymmetricCipherKeyPair keys = kpg.GenerateKeyPair();


            //Write PEM encoded private key
            var sw = new StringWriter();
            var pw = new PemWriter(sw);
            pw.WriteObject(keys.Private);
            pw.Writer.Flush();
            var pemRsaPublicKey = sw.ToString();

            //Write PEM encoded public key
            sw = new StringWriter();
            pw = new PemWriter(sw);
            pw.WriteObject(keys.Public);
            pw.Writer.Flush();
            var pemRsaPrivateKey = sw.ToString();

            //Create PGP secret key from keypair using the same seed
            var secretKey = new PgpSecretKey(PgpSignature.DefaultCertification,
                PublicKeyAlgorithmTag.RsaGeneral,
                keys.Public, keys.Private, keyDate, identity,
SymmetricKeyAlgorithmTag.Cast5, null, null, null,
                new SecureRandom(seed));

            //Write armored secret key
            var secretMemStream = new MemoryStream();
            var secretArmoredStream = new ArmoredOutputStream(secretMemStream);
            secretKey.Encode(secretArmoredStream);
            secretArmoredStream.Close();
            var ascPgpSecretKey =
Encoding.ASCII.GetString(secretMemStream.ToArray());

            //Write armored public key
            var pubMemStream = new MemoryStream();
            var pubArmoredStream = new ArmoredOutputStream(pubMemStream);
            secretKey.PublicKey.Encode(pubArmoredStream);
            pubArmoredStream.Close();
            var ascPgpPublicKey =
Encoding.ASCII.GetString(pubMemStream.ToArray());

            Console.WriteLine(pemRsaPrivateKey);
            Console.WriteLine(pemRsaPublicKey);

            Console.WriteLine(ascPgpPublicKey);
            Console.WriteLine(ascPgpSecretKey);

        }

    }
}

Reply via email to