我目前正在开发一个应用程序,它将创建一个文本文件,使用PGP公钥(不是文件,但是十六进制数字和pgp名称)加密文件,并按计划将其发布到FTP。我发布信息的人需要对文件进行PGP加密并共享公钥(不是文件,而是十六进制数和pgp名)。
我被困的地方是PGP加密部分。我看到了如何使用弹性城堡库使用公钥文件或公钥环(我理解是一组键)来加密文本文件的示例。但我的信息是32位十六进制密钥和一个PGP名称。我不确定如何使用此信息加密文件。我是否应该要求对方向我发送公钥文件?是否可以根据我的信息创建公钥文件?我对PGP加密很新,并且在经过大量谷歌搜索后没有提供任何信息,所以请帮忙。
这是我到目前为止加密文件的代码。如您所见,代码将文件作为公钥的输入而不是十六进制十进制代码和名称。我的问题是,是否可以使用pgp名称和十六进制数进行pgp加密?
public class PGPHelper
{
private PgpEncryptionKeys m_encryptionKeys;
private const int BufferSize = 0x10000;
/// <summary>
/// Instantiate a new PgpEncrypt class with initialized PgpEncryptionKeys.
/// </summary>
/// <param name="encryptionKeys"></param>
/// <exception cref="ArgumentNullException">encryptionKeys is null</exception>
public PGPHelper(PgpEncryptionKeys encryptionKeys)
{
if (encryptionKeys == null)
{
throw new ArgumentNullException("encryptionKeys", "encryptionKeys is null.");
}
m_encryptionKeys = encryptionKeys;
}
/// <summary>
/// Encrypt and sign the file pointed to by unencryptedFileInfo and
/// write the encrypted content to outputStream.
/// </summary>
/// <param name="outputStream">The stream that will contain the
/// encrypted data when this method returns.</param>
/// <param name="fileName">FileInfo of the file to encrypt</param>
public void Encrypt(Stream outputStream, FileInfo unencryptedFileInfo)
{
if (outputStream == null)
{
throw new ArgumentNullException("outputStream", "outputStream is null.");
}
if (unencryptedFileInfo == null)
{
throw new ArgumentNullException("unencryptedFileInfo", "unencryptedFileInfo is null.");
}
if (!File.Exists(unencryptedFileInfo.FullName))
{
throw new ArgumentException("File to encrypt not found.");
}
using (Stream encryptedOut = ChainEncryptedOut(outputStream))
{
using (Stream literalOut = ChainLiteralOut(encryptedOut, unencryptedFileInfo))
using (FileStream inputFile = unencryptedFileInfo.OpenRead())
{
WriteOutput(literalOut, inputFile);
}
}
}
private static void WriteOutput(Stream literalOut,
FileStream inputFile)
{
int length = 0;
byte[] buf = new byte[BufferSize];
while ((length = inputFile.Read(buf, 0, buf.Length)) > 0)
{
literalOut.Write(buf, 0, length);
}
}
private Stream ChainEncryptedOut(Stream outputStream)
{
PgpEncryptedDataGenerator encryptedDataGenerator;
encryptedDataGenerator =
new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes, new SecureRandom());
encryptedDataGenerator.AddMethod(m_encryptionKeys.PublicKey);
return encryptedDataGenerator.Open(outputStream, new byte[BufferSize]);
}
private static Stream ChainLiteralOut(Stream encryptedOut, FileInfo file)
{
PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
return pgpLiteralDataGenerator.Open(encryptedOut, PgpLiteralData.Binary, file);
}
}
public class PgpEncryptionKeys
{
public PgpPublicKey PublicKey { get; private set; }
/// <summary>
/// Initializes a new instance of the EncryptionKeys class.
/// Two keys are required to encrypt and sign data. Your private key and the recipients public key.
/// The data is encrypted with the recipients public key and signed with your private key.
/// </summary>
/// <param name="publicKeyPath">The key used to encrypt the data</param>
/// <exception cref="ArgumentException">Public key not found. Private key not found. Missing password</exception>
public PgpEncryptionKeys(string publicKeyPath, string privateKeyPath, string passPhrase)
{
if (!File.Exists(publicKeyPath))
{
throw new ArgumentException("Public key file not found", "publicKeyPath");
}
PublicKey = ReadPublicKey(publicKeyPath);
}
#region Public Key
private PgpPublicKey ReadPublicKey(string publicKeyPath)
{
using (Stream keyIn = File.OpenRead(publicKeyPath))
using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))
{
PgpPublicKeyRingBundle publicKeyRingBundle = new PgpPublicKeyRingBundle(inputStream);
PgpPublicKey foundKey = GetFirstPublicKey(publicKeyRingBundle);
if (foundKey != null)
{
return foundKey;
}
}
throw new ArgumentException("No encryption key found in public key ring.");
}
private PgpPublicKey GetFirstPublicKey(PgpPublicKeyRingBundle publicKeyRingBundle)
{
foreach (PgpPublicKeyRing kRing in publicKeyRingBundle.GetKeyRings())
{
PgpPublicKey key = kRing.GetPublicKeys()
.Cast<PgpPublicKey>()
.Where(k => k.IsEncryptionKey)
.FirstOrDefault();
if (key != null)
{
return key;
}
}
return null;
}
#endregion