David Munsa
David Munsa

Reputation: 893

encrypt file with BouncyCastle , output look corrupted

so i using this code to encrypt my file

as you can see iam using public PGP

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.6 (GNU/Linux)

masdSFVkRBADYxPZYC+nu9nhSVkxcVkVJ5axZKzCRuygqUxka
kZIBy2CAQVKz5dBkRaUkaaksbcyautks7asaov26Fc9cT25Rvnh7
wYIJhcRoIl4cxashdgutasd0qfcOnVB5JVCQDhXclBW7kwCgkoUW
....
...
...
-----END PGP PUBLIC KEY BLOCK-----

the code works fine but i think the data of the encrepted file is corrupted

because it doesnt comes out in this format (like the key)

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.2.6 (GNU/Linux)

masdSFVkRBADYxPZYC+nu9nhSVkxcVkVJ5axZKzCRuygqUxka
kZIBy2CAQVKz5dBkRaUkaaksbcyautks7asaov26Fc9cT25Rvnh7
wYIJhcRoIl4cxashdgutasd0qfcOnVB5JVCQDhXclBW7kwCgkoUW
....
...
...
-----END PGP PUBLIC KEY BLOCK-----

am i wrong?

dont the output should be in the same format ?

using System;
using System.Xml;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Text;

using Org.BouncyCastle.Bcpg.OpenPgp;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.IO;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Bcpg;

class CPGPencrypt
{
    private static PgpPublicKey ReadPublicKey(Stream inputStream)
    {

        inputStream = PgpUtilities.GetDecoderStream(inputStream);

        PgpPublicKeyRingBundle pgpPub = new PgpPublicKeyRingBundle(inputStream);

        //
        // we just loop through the collection till we find a key suitable for encryption, in the real
        // world you would probably want to be a bit smarter about this.
        //

        //
        // iterate through the key rings.
        //

        foreach (PgpPublicKeyRing kRing in pgpPub.GetKeyRings())
        {
            foreach (PgpPublicKey k in kRing.GetPublicKeys())
            {
                if (k.IsEncryptionKey)
                {
                    return k;
                }
            }
        }

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

    private static byte[] EncryptFile(byte[] clearData, string fileName, PgpPublicKey encKey, bool withIntegrityCheck)
    {

        MemoryStream bOut = new MemoryStream();

        PgpCompressedDataGenerator comData = new PgpCompressedDataGenerator(
            CompressionAlgorithmTag.Zip);

        Stream cos = comData.Open(bOut); // open it with the final destination
        PgpLiteralDataGenerator lData = new PgpLiteralDataGenerator();

        // we want to Generate compressed data. This might be a user option later,
        // in which case we would pass in bOut.
        Stream pOut = lData.Open(
            cos,                    // the compressed output stream
            PgpLiteralData.Binary,
            fileName,               // "filename" to store
            clearData.Length,       // length of clear data
            DateTime.UtcNow         // current time
        );

        pOut.Write(clearData, 0, clearData.Length);

        lData.Close();
        comData.Close();

        PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());

        cPk.AddMethod(encKey);

        byte[] bytes = bOut.ToArray();

        MemoryStream encOut = new MemoryStream();
        Stream os = encOut;

        Stream cOut = cPk.Open(os, bytes.Length);
        cOut.Write(bytes, 0, bytes.Length);  // obtain the actual bytes from the compressed stream
        cOut.Close();

        encOut.Close();

        return encOut.ToArray();
    }

    public static string Encrypt(string file_name,string file_to_read)
    {


        try
        {

            byte[] dataBytes = File.ReadAllBytes(file_to_read);
            Stream keyIn = File.OpenRead("pgpdata-public.asc");
            Stream outStream = File.Create(@"myfolder\"+file_name);
            byte[] encrypted = EncryptFile(dataBytes, @"myfolder\"+file_name, ReadPublicKey(keyIn), false);
            outStream.Write(encrypted, 0, encrypted.Length);
            keyIn.Close();
            outStream.Close();
        }
        catch (Exception e)
        {
            return e.Message;
        }
        return file_name;

    }


}

Upvotes: 0

Views: 2207

Answers (1)

Jens Erat
Jens Erat

Reputation: 38662

There are different encoding schemes in OpenPGP, namely

  1. binary data and
  2. ASCII armored data.

Especially for key exchange, normally the ASCII armored format is preferred as it is more robust and easy to recognize. For mail exchange, it is mandatory (for 7 bit compatibility). The binary version also has advantages, especially regarding performance and storage (bandwith) requirements.

For example, GnuPG will use the binary encoding by default, unless you request the ASCII armored version using the option --ascii or abbreviated -a.

It look like your code is outputting the binary encoding, but works all fine.

You can easily test by trying to decrypt (eg. using GnuPG: gpg --decrypt file.pgp). Alternatively, you can dump the OpenPGP packets the file contains by using gpg --list-packets file.pgp or using the more verbose utility pgpdump, which is available in most (unix) package repositories: pgpdump file.pgp. Unlike gpg --list-packets, it also resolves packet and algorithm identifiers to human readable strings (where gpg --list-packets just dumps their numeric IDs).

Upvotes: 1

Related Questions