编辑:此代码有效。关键文本每次都不同,但关键材料是相同的。我已经更新了下面的代码,从控制台收集密钥创建的数据,没有回声。
我想通过livecd从livecd生成一个Pgp密钥对 短语,分发公钥并用它来加密个人数据 在我将它存储在谷歌驱动器之前,但从不写私钥 磁盘。
我意识到我可以直接使用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);
}
}
}
答案 0 :(得分:0)
谢谢Duncan!
有效。
即使基础RSA密钥相同,每次出现的PGP密钥的ASCII装甲文本也不同。
但是,我能够生成密钥对,使用公钥加密文件,然后生成新密钥对,并使用该新私钥解密文件。