0

I need to create a .pdf file using a ReportDocument. in c#. That .pdf file need to,

  • Need to Encrypted with AES/CBC/PKCS5Padding
  • Need to use Secret Key and Initialization vector
  • Need to store the encrypted .pdf to the given file path.
  • Should not directly save the .pdf and then do the encryption later. that not valid

My idea is convert the ReportDocument to a byte array and to the task. I tried with following two methods but there are two some problems

Method 1

   internal void ExportAndSaveEncryptedPDF1(ReportDocument reportDocument, string path, byte[] key, byte[] iv)
    {
        MemoryStream reportStream = new MemoryStream();
        reportDocument.ExportToStream(ExportFormatType.PortableDocFormat, reportStream);
        byte[] reportBytes = reportStream.ToArray();
        byte[] encryptedBytes = Encrypt1(reportBytes, key, iv);
        File.WriteAllBytes(path, encryptedBytes);
    }

    public static byte[] Encrypt1(byte[] data, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7;
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                    return memoryStream.ToArray();
                }
            }
        }
    }

Problem of method 1

There is a compile error in the following line. Thea cause is, there are no any overloaded method for the two parameters. So I cannot work with report stream

reportDocument.ExportToStream(ExportFormatType.PortableDocFormat, reportStream);

Method 2

   internal void ExportAndSaveEncryptedPDF2(ReportDocument reportDocument, string path, byte[] key, byte[] iv)
    {           
        using (MemoryStream reportStream = new MemoryStream())
        {
            ExportOptions exportOptions = new ExportOptions();
            exportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
            exportOptions.ExportDestinationType = ExportDestinationType.Stream;
            exportOptions.Stream = reportStream;
            reportDocument.Export(exportOptions);
            byte[] reportBytes = reportStream.ToArray();
            byte[] encryptedBytes = Encrypt2(reportBytes, key, iv);
            File.WriteAllBytes(path, encryptedBytes);
        }
    }

    public static byte[] Encrypt2(byte[] data, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7;
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                    return memoryStream.ToArray();
                }
            }
        }
    }

Problem of Method 2

There are problems with following lines

ExportOptions exportOptions = new ExportOptions();
exportOptions.ExportDestinationType = ExportDestinationType.Stream;
exportOptions.Stream = reportStream;

The reason is is,

1.ExportDestinationType does not contain a definition of Stream

2.ExportOptions does not contain a definition of Stream

Anyway I need to create an encrypted .pdf to a given location in c#. Do you know a fix for this problem?

ruwan liyanage
  • 419
  • 2
  • 11
  • 24

1 Answers1

0

Finally I found a way to fix this problem.

    internal void ExportAndSaveEncryptedPDF(ReportDocument reportDocument, string path, byte[] key, byte[] iv)
    {
        Stream stream = reportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
        byte[] streamAsByteArray = ConvertStreamToByteArray(stream);
        byte[] encryptedByteArray = EncryptToPDF(streamAsByteArray, key, iv);
        File.WriteAllBytes(path, encryptedByteArray);
        Log.InfoFormat("Report : Successfully exported enctypted .pdf to {0}] when printout tracing", _reportXmlData.ReportConfigurationData.PDFTraceFile);
    }

    internal byte[] ConvertStreamToByteArray(Stream stram)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = stram.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

    public static byte[] EncryptToPDF(byte[] data, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            aes.Padding = PaddingMode.PKCS7;
            aes.Mode = CipherMode.CBC;
            using (MemoryStream memoryStream = new MemoryStream())
            {
                ICryptoTransform encryptor = aes.CreateEncryptor();
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                    return memoryStream.ToArray();
                }
            }
        }
    }

we can create a Stream and can convert it to a byte array. then after we can work with that byte array to encryption and saving

ruwan liyanage
  • 419
  • 2
  • 11
  • 24