如何使用PGP十六进制ID和PGP名称而不是C#中的公钥文件加密文件

时间:2013-02-15 16:29:41

标签: c# bouncycastle pgp

我目前正在开发一个应用程序,它将创建一个文本文件,使用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

0 个答案:

没有答案