AwkwardCoder
AwkwardCoder

Reputation: 25631

Public key encryption using Bouncy Castle, how do I know the SymmetricKeyAlgorithm

I have a public PGP key to encrypt a file, and when I use a tool like Kelopatra I can encrypt the file and the other party can de-crypt successfully.

But what values do I need to configure when doing this from C# code using Bouncy Castle?

Not sure the value for SymmetricKeyAlgorithmTag or CompressionAlgorithmTag.

Or put it another way, how do I determine from the PGP key what values I should use?

I tried SymmetricKeyAlgorithmTag.Des and it can not be de-crypted with the private key.

public static class Pgp
{
  public static void EncryptFile(
        string sourceFile,
        string destinationFile,
        string encKeyFileName)
  {
        var pkr = LoadPublicKey(encKeyFileName);
        var key = GetFirstPublicEncryptionKeyFromRing(pkr);
        EncryptFile(sourceFile, destinationFile, key);
  }

  private static void EncryptFile(string sourceFile, string destinationFile, PgpPublicKey encKey)
  {
        using var compressionStream = new MemoryStream();
        var compressedDataGenerator = new PgpCompressedDataGenerator(**CompressionAlgorithmTag.Uncompressed**);
        PgpUtilities.WriteFileToLiteralData(compressedDataGenerator.Open(compressionStream),
                                            PgpLiteralData.Binary, new FileInfo(sourceFile));

        var dataGenerator = new PgpEncryptedDataGenerator(**SymmetricKeyAlgorithmTag.Des**, true, new SecureRandom());
        dataGenerator.AddMethod(encKey);

        var bytes = compressionStream.ToArray();
        using Stream outputFileStream = File.Create(destinationFile);
        using var dataGeneratorStream = dataGenerator.Open(outputFileStream, bytes.Length);
        dataGeneratorStream.Write(bytes, 0, bytes.Length);
  }

  private static PgpPublicKey GetFirstPublicEncryptionKeyFromRing(PgpPublicKeyRing keyRing)
  {
        foreach (var publicKey in keyRing.GetPublicKeys())
              if (publicKey.IsEncryptionKey)
                    return publicKey;

        throw new ArgumentException("Can't find encryption key in key ring.");
  }

  private static PgpPublicKeyRing LoadPublicKey(string filePath)
  {
        using Stream fileStream = File.OpenRead(filePath);
        var pubArmoredStream = new ArmoredInputStream(fileStream);
        var pgpObjectFactory = new PgpObjectFactory(pubArmoredStream);
        object nextPgpObject = pgpObjectFactory.NextPgpObject();
        return nextPgpObject as PgpPublicKeyRing;
  }
}

Upvotes: 0

Views: 36

Answers (0)

Related Questions