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