Получить / прочитать общедоступный сертификат для шифрования PDF с использованием файла .pfx с паролем через библиотеку / метод itext7

У меня есть функции iText7, которые я использую,

прямо сейчас я пытаюсь зашифровать свой PDF-файл, используя сертификат в формате .pfx с паролем.

Дело в том, что функция не может прочитать .pfx, потому что она не предоставляет пароль, как показано ниже.

using System.IO;
using iText.Kernel.Pdf;
using Org.BouncyCastle.X509;

namespace iText.Samples.Sandbox.Security
{
    public class EncryptWithCertificate
    {
        public static readonly String DEST = "results/sandbox/security/encrypt_with_certificate.pdf";
        public static readonly String SRC = "../../../resources/pdfs/hello.pdf";
        public static readonly String PUBLIC = "../../../resources/encryption/test.cer";

        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();

            new EncryptWithCertificate().ManipulatePdf(DEST);
        }

        public X509Certificate GetPublicCertificate(String path)
        {
            using (FileStream stream = File.Open(path, FileMode.Open))
            {
                X509CertificateParser parser = new X509CertificateParser();
                X509Certificate readCertificate = parser.ReadCertificate(stream);
                return readCertificate;
            }
        }

        protected void ManipulatePdf(String dest)
        {
            // The file created by this example can not be opened, unless
            // you import the private key stored in test.p12 in your certificate store.
            // The password for the p12 file is kspass.
            X509Certificate cert = GetPublicCertificate(PUBLIC);

            PdfDocument document = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest,
                new WriterProperties().SetPublicKeyEncryption(
                    new[] {cert},
                    new[] {EncryptionConstants.ALLOW_PRINTING},
                    EncryptionConstants.ENCRYPTION_AES_256)));
            document.Close();
        }
    }
}

Если я попытаюсь загрузить обычный файл .cer, он пройдет нормально для GetPublicCertificate. Нет проблем. Но я пытаюсь зашифровать его с помощью файла .pfx, поскольку Adobe Acrobat может регистрировать цифровой идентификатор только в формате .p12/.pkf, и функция выдает ошибку.

Ошибка

Org.BouncyCastle.Security.Certificates.CertificateException
      HResult=0x80131500
      Message=Failed to read certificate
      
    
    Inner Exception 1:
    ArgumentException: Unknown object in GetInstance: Org.BouncyCastle.Asn1.DerInteger
    Parameter name: obj

Я надеюсь зашифровать PDF-файл с помощью сертификата, поскольку срок действия сертификата может быть установлен в любое время в соответствии с тем, что я установил, и пользователь может просматривать файл PDF только на основе истечения срока действия сертификата.

Заранее спасибо.


person Iman Manan    schedule 06.05.2021    source источник
comment
какова ваша конечная цель? Ограничить доступ к PDS на основе действительности сертификата? Тогда ваше решение совершенно неверно. С самого начала и до самого конца.   -  person Crypt32    schedule 06.05.2021
comment
Да @Crypt32, конечная цель — добавить ограничение в PDF. Только пользователи с сертификатом могут открывать PDF-файл. Мне также удалось создать .pfx, сейчас я просто хочу зашифровать сертификат в выбранный PDF-файл. Могу я узнать, почему мое решение совершенно неверно в соответствии с тем, что вы сказали? Спасибо ^_^   -  person Iman Manan    schedule 06.05.2021
comment
Потому что вы не можете установить ограничения по времени. Пользователь может получить доступ к PDF-файлу, если у него есть закрытый ключ. Срок действия сертификата здесь роли не играет. Ваше решение эквивалентно шифрованию на основе пароля. И имейте в виду, что как только пользователь получает незашифрованный PDF-файл, пользователь может сохранить незашифрованный PDF-файл и получить неограниченный доступ даже без сертификата и закрытого ключа.   -  person Crypt32    schedule 06.05.2021
comment
Я вижу @Crypt32. Я попытался реализовать javascript для шифрования на основе пароля и ограничения доступа к дате истечения срока действия в PDF. единственное, файл можно открыть в программе просмотра, такой как Google Chrome, Firefox (браузер), что противоречит цели. Итак, я пытаюсь найти это решение, поскольку заметил, что сертификат может установить дату истечения срока действия. Если у вас есть лучшее решение, я ценю ваш ответ и предложение ^_^.   -  person Iman Manan    schedule 06.05.2021
comment
вы не можете установить время истечения срока действия на основе сертификатов, это не имеет значения. Я бы посмотрел на решения RMS (службы управления правами), которые предназначены для решения конкретной проблемы.   -  person Crypt32    schedule 06.05.2021
comment
@ Crypt32 Хорошо, я посмотрю на RMS, еще раз спасибо за ваше время! Очень ценю это.   -  person Iman Manan    schedule 06.05.2021
comment
@Crypt32, у меня только что появилась идея.... Если я зашифрую PDF с помощью сертификата и в то же время... реализую javascript для встраивания проверки истечения срока.... это сработает? Поскольку сертификат можно использовать, чтобы запретить пользователю открывать в любом браузере средство просмотра PDF... в то время как javascript может иметь определенную безопасность, ограничение.... просто идея... Я попытался найти RMS... не так уж много можно интегрировать в С#.... ура   -  person Iman Manan    schedule 06.05.2021
comment
Имейте в виду, что клиент может манипулировать временем на машине и нарушать ваши ограничения. Вам нужна внешняя система управления (предоставляемая RMS), которая будет принимать решение о том, разрешена ли запрошенная операция и как долго она разрешена.   -  person Crypt32    schedule 06.05.2021


Ответы (1)


Согласно вашему исходному сообщению, ваше намерение:

Я надеюсь зашифровать PDF-файл с помощью сертификата, поскольку срок действия сертификата может быть установлен в любое время в соответствии с тем, что я установил, и пользователь может просматривать файл PDF только на основе истечения срока действия сертификата.

По сути, вы хотите предоставить авторизованному пользователю ограниченный по времени доступ к PDF. Решение, которое вы пытаетесь построить в образце кода, не решает проблему. Действительность сертификата для шифрования данных не имеет значения, так как действительность сертификата не проверяется при расшифровке. На самом деле даже сертификат не нужен, достаточно иметь закрытый ключ для расшифровки данных. Другими словами, шифрование на основе сертификата эквивалентно шифрованию на основе пароля. Что добавляет сертификат - более простой способ найти ключ дешифрования (секрет), ничего больше.

Кроме того, после расшифровки данных клиент может сохранить данные в незашифрованном виде, поэтому ваши ограничения бесполезны. Даже если вы попытаетесь установить временные ограничения в JavaScript или что-то еще локально (а JavaScript выполняется только локально), это не решение. Пока клиент может управлять датой/временем на устройстве, клиент всегда может установить желаемую дату/время, чтобы нарушить ваши ограничения.

Ваша проблема не может быть решена без создания стороннего объекта, который будет принимать решения о том, разрешена ли запрошенная операция, применять необходимые ограничения и минимизировать вероятность утечки данных в незашифрованном виде (только минимизировать, а не предотвращать). Такая функциональность реализована в управлении цифровыми правами (DRM) или службе управления правами (RMS), и вы вам нужно построить свое решение на основе этих инструментов, а не пытаться интегрировать их в свое решение. Существует множество поставщиков, предлагающих решения DRM/RMS, на которые вы можете обратить внимание и использовать их функциональные возможности для создания решения, отвечающего вашим требованиям.

person Crypt32    schedule 06.05.2021
comment
Другими словами, шифрование на основе сертификата равно шифрованию на основе пароля. - Что ж, оно одинаково в том, что касается полезности для задачи OP. В общем не равно конечно. - person mkl; 20.07.2021