Шифрование и дешифрование PGP с помощью BouncyCastle v1.8.6 - PullRequest
0 голосов
/ 14 апреля 2020

Здравствуйте, PGP и гуру шифрования,

Я пытаюсь реализовать свой собственный компонент PGP в одном из моих проектов с использованием инфраструктуры BouncyCastle v1.8.6. Я получаю этот вывод:

-----BEGIN PGP MESSAGE-----
Version: BCPG C# v1.8.6.0

hQIMA4Iw6uZzIOIHAQ/8DxA38ahmnjo9Sjfyyu9buwhPYyuC23XenPcSZmscYArt
5V7jlMkqBWTAE2ri/e3ZZot4nzmee9vpBD28vxuSC5P9IzENnqYH5iDX2QQDzaxY
ou63NNNvxdEhvTpj4NrJ5N/9fpX208BmLw+Ge2UkysCBsnvAas6B7gPcK9+F5IbM
j0z9fa0SxlRw+kpNoDQTFUt2Ffp/gK/oWgC1gvDxnMLvpL/MI8VMQ4ayhftdv2xA
7+H0oLFv97fIqmG/fMb5pC+MNcSAu9RPYjIan9X6esPW5cfoZ5A84m0SvHFuC2Nn
Xh9oHji1ZANe1wMR2aLQli8kyyDwD9ywWa8q4ZcpGHnJGRBQbsHJQI92R/TDbn8c
60ZA8nnFSzzw/erU5N6Z8XCH3HEeYdYtuLRqr8QmP8WxS/+yxh1X/csXCQE9KU9p
hIhD8s8teJIyFZnLzlG36NdwSIPSrZsi5hRhz3DHM45A3AukYUtvFXInX/ThAMrs
Y+Ie4C3oBNiKzuDtvSPhYoWzyFQA5UXINW3Np9tYfk+Ze7icoOSeFFQbLhN5i2Vn
hEJmh5RUyd7gdGgNbsGO6gJF4CUDVeNrsd3VnMUIzEz4vZSaLDWvhs+1tMlwjOE8
E/FQcxN5Eqc0qPPLu32I93Zhgujz03Lmp1l1WRSDxdhBIgxRCg3bGZ41RUYTfsLJ
wOrOToFSD2Sc81ah5/5QB9mYRuLU4LJWAF1mQ+JaksuS1l31myIngzgRocJvhxpL
KFxnf7zLR8NK90YP0euTvvRDwZXQ+PDswK4kfV8fnziNDwUM+B2DxLPK0hH0Mb0h
fwnMWkjiAXE4E0u1I7dvHV16e1zjc79IjPZ60YjsELzqWQKPR4oTM/+VJq1VZsp+
19rvC4dbvvaFNQ4XkQPN3POptg+kSR6Wdy+tFY/7afUBnpUMtLkMx1vVVXZWTsO4
EAoBEN5ysh5YelayVn9fpB2VILwS0QcKVDVdfXnEkHZfvq4AQQX/1k4jFLrfHuf8
32gZsLzUHQQ0snMgqcdf6X+HcuYdauB09QgqQK992ggQrZKM+7QOUPSlDYrdWi/R
i3YEvyyc5u96VonHP8jlM7PQhcOvffQ4bz9D+zTozUg2MyjByZZy5Eerg5MP6dfF
1q2OPuufViB0DeQvYFWtdY5jWmkZh7NIaD6octA63hHU7Cyu7fMVIMx95XrEIXNm
Lsett8V9RyfyQyNW2wFLzPmxl24klgINv92thiE2A3w+KnN8PgHBfA6xflY=
=HT2J
-----END PGP MESSAGE-----

, используя эту реализацию:

public void EncryptAndSign() {
    _CompressionAlgorithm = CompressionAlgorithmTag.Uncompressed;
    _SymmetricKeyAlgorithm = SymmetricKeyAlgorithmTag.TripleDes;
    _PgpSignatureType = PgpSignature.CanonicalTextDocument;
    _FileType = PGPFileType.Binary;
    _HashAlgorithmTag = HashAlgorithmTag.Sha1;

    string
    var = "Hello this me first PGP Encrypt";

    byte[] data = Encoding.ASCII.GetBytes(var);

    PgpLiteralDataGenerator pgpLiteralDataGenerator = new PgpLiteralDataGenerator();
    PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(_SymmetricKeyAlgorithm, false, new SecureRandom());
    encryptedDataGenerator.AddMethod(m_encryptionKeys.PublicKey);

    using(var sout = new MemoryStream()) {
        using(var armoredOut = new ArmoredOutputStream(sout)) {
            using(var clearOut = new MemoryStream()) {

                PublicKeyAlgorithmTag tag = m_encryptionKeys.SecretKey.PublicKey.Algorithm;
                PgpSignatureGenerator pgpSignatureGenerator = new PgpSignatureGenerator(tag, _HashAlgorithmTag);
                pgpSignatureGenerator.InitSign(_PgpSignatureType, m_encryptionKeys.PrivateKey);
                foreach(string userId in m_encryptionKeys.SecretKey.PublicKey.GetUserIds()) {
                    PgpSignatureSubpacketGenerator subPacketGenerator = new PgpSignatureSubpacketGenerator();
                    subPacketGenerator.SetSignerUserId(false, userId);
                    pgpSignatureGenerator.SetHashedSubpackets(subPacketGenerator.Generate());
                    // Just the first one!
                    break;
                }

                pgpSignatureGenerator.GenerateOnePassVersion(false).Encode(clearOut);

                using(var literalOut = pgpLiteralDataGenerator.Open(clearOut, PgpLiteralData.Text, "", data.Length, DateTime.Now)) {
                    literalOut.Write(data, 0, data.Length);
                    pgpSignatureGenerator.Update(data, 0, data.Length);
                }

                pgpSignatureGenerator.Generate().Encode(clearOut);

                var clearData = clearOut.ToArray();

                using(var encryptOut = encryptedDataGenerator.Open(armoredOut, clearData.Length)) {
                    encryptOut.Write(clearData, 0, clearData.Length);
                }
            }
        }

        var d = ASCIIEncoding.ASCII.GetString(sout.ToArray());
        File.WriteAllText(@"D:\pgp\MyTestEncrypt.txt", d);
    }
}

Когда я пытаюсь расшифровать указанное выше сообщение PGP, я получаю эту ошибку:

attempt to process message to long for cipher

Нет innerException, это нуль. Но есть эта трассировка стека:

   at Org.BouncyCastle.Crypto.BufferedAsymmetricBlockCipher.ProcessBytes(Byte[] input, Int32 inOff, Int32 length)
   at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyEncryptedData.RecoverSessionData(PgpPrivateKey privKey)
   at Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyEncryptedData.GetDataStream(PgpPrivateKey privKey)
   at PGPEncryption.PGPDecrypt.decrypt(Stream input, String outputpath) in C:\Users\test\source\repos\ConsoleApp2\ConsoleApp2\PGPDecrypt.cs:line 50
e.Source
BouncyCastle.Crypto

Расшифровка реализации:

public void decrypt(Stream input, string outputpath) {

    try {
        using(FileStream fsEncryptedFile = File.Open(@"D:\pgp\MyTestEncrypt.txt", FileMode.Open)) {
            using(Stream decoderStream = PgpUtilities.GetDecoderStream(fsEncryptedFile)) {
                PgpObjectFactory factory = new PgpObjectFactory(decoderStream);
                PgpObject obj = factory.NextPgpObject();
                if (! (obj is PgpEncryptedDataList)) {
                    obj = factory.NextPgpObject(); // first object might be a PGP marker packet
                }
                PgpEncryptedDataList edl = obj as PgpEncryptedDataList;

                foreach(PgpPublicKeyEncryptedData data in edl.GetEncryptedDataObjects()) {
                    PgpPrivateKey privateKey = GetPrivateKey(@"D:\pgp\SecyretKey\openpgp_test.asc");

                    PgpObjectFactory plainFactory = new PgpObjectFactory(data.GetDataStream(pgpKeys.PrivateKey));
                    PgpObject message = plainFactory.NextPgpObject();
                    if (message is PgpCompressedData) {
                        message = new PgpObjectFactory(((PgpCompressedData) message).GetDataStream()).NextPgpObject();
                    }
                    if (message is PgpLiteralData) {
                        PgpLiteralData ld = (PgpLiteralData) message;
                        using(FileStream outStream = File.Create(@"D:\pgp\MessageOut_Decrypt.txt")) {
                            Stream inStream = ld.GetInputStream();
                            byte[] buffer = new byte[0x100000];
                            int count = inStream.Read(buffer, 0, buffer.Length);
                            while (count > 0) {
                                outStream.Write(buffer, 0, count);
                                count = inStream.Read(buffer, 0, buffer.Length);
                            }
                            outStream.Close();
                        }
                    }
                    else {
                        Console.WriteLine("ERROR: Unknown type of message in PGP file: {0}", message.GetType().FullName);
                    }

                }
            }
        }
    }
    catch(Exception e) {
        throw new Exception(e.Message);
    }
}

У меня есть 2 вопроса:

  1. Как мне удалить " Версия "часть в генерируемом сообщении PGP?

  2. Почему я получаю сообщение об ошибке при попытке расшифровать сообщение?

...