Техническа статия

PDF 2.0 AES-GCM криптиране в Delphi: ISO/TS 32003

PDFiumPas записва ISO/TS 32003 криптиране чрез SaveAsEncrypted: задайте Revision на erR7 и всеки низ и stream се защитават с AES-256 в GCM режим, authenticated шифърът, който PDF 2.0 придоби през 2023. Задайте и EnableIntegrityProtection и документът носи и самостоятелен PDF MAC токен, който ValidatePdfMac проверява от страната на четенето

Това са две различни защити, които хората рутинно бъркат. GCM authentication-ира всяка криптирана стойност. MAC-ът authentication-ира документа като цяло. Искате и двете, по различни причини

Какво добавя GCM, което CBC никога не е предоставял?

Authentication на ciphertext-а. AES-256 в CBC режим, схемата AESV3 в ISO 32000-2, пази съдържанието конфиденциално и не казва нищо за това дали е пристигнало непроменено. CBC е malleable по конкретни, добре изучени начини: атакуващ, който може да обръща битове в ciphertext-а, произвежда предвидими промени в plaintext-а на следващия блок, и нищо във формата не забелязва

GCM затваря това. Всяка криптирана стойност носи 16-байтов authentication tag, сериализиран изцяло, както изисква ISO/TS 32003, а декриптирането се проваля, вместо да върне променен plaintext, когато tag-ът не съвпада. В PDF термини, подправен низ или stream в AESV4 документ е твърда грешка в момента на употреба, не странна стойност, разпространяваща се във вашето приложение. Encrypt речникът маркира това с /CFM /AESV4 и V 6 / R 7, заедно с extensions запис, деклариращ /ExtensionLevel 32003 и /ExtensionRevision (:2023)

Диаграма, противопоставяща обработката на подправяне в AES-256-CBC и AESV4 GCM при запис на криптирани PDF от Delphi с PDFiumPas
AES-256-CBC обръщане на бит се декриптира в променен plaintext, докато всяка AESV4 GCM стойност носи 16-байтов таг, превръщащ същото подправяне в твърда грешка при декриптиране

Три ревизии, три екосистеми

TPdfEncryptionRevision предлага erR5, erR6 и erR7, а изборът е по-скоро решение за съвместимост, отколкото за криптография. R5 е оригиналната AES-256 схема, публикувана като разширение на PDF 1.7, с единичен SHA-256 хеш на паролата, и се отваря в практически всичко от последните петнайсет години. R6 е укрепеното извеждане на ключ, стандартизирано в ISO 32000-2, използващо итеративната конструкция SHA-256/384/512 на алгоритъм 2.B, и е онова, което текущ работен процес за PDF 2.0 или PDF/A-4 очаква. R7 е ISO/TS 32003, използваща същото извеждане 2.B с AES-GCM като шифър

Поддръжката в четците следва точно този ред, а поддръжката на R7 все още е тънка извън текущите основни зрители. Това е същият компромис, който управлява всяка функция на PDF 2.0: най-новата опция е най-доброто инженерство и най-тясната аудитория. Решавайте според това кой трябва да отвори файла, а ако отговорът е „система за архивни записи, която никой не е обновявал от 2019“, отговорът е R5 независимо какво предпочита политиката за сигурност

uses
  PDFium, FPdfEncrypt;

var
  Pdf: TPdf;
  Opts: TPdfEncryptOptions;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'quarterly-report.pdf';
    Pdf.LoadDocument;

    Opts := TPdfEncryptOptions.Default;
    Opts.UserPassword := 'open-secret';
    Opts.OwnerPassword := 'admin-secret';
    Opts.EncryptMetadata := True;
    Opts.Revision := erR7;                    // ISO/TS 32003 AESV4-GCM
    Opts.EnableIntegrityProtection := True;   // самостоятелен PDF MAC токен

    if not Pdf.SaveAsEncrypted('quarterly-report.enc.pdf', Opts) then
      raise Exception.Create('Encrypted save failed');
  finally
    Pdf.Free;
  end;
end;

Защо документен MAC върху authenticated шифър?

Защото GCM tag-овете защитават стойностите, не подредбата на стойностите. Всеки низ и stream в AESV4 документ е индивидуално authentication-иран, но cross-reference таблицата, номерацията на обектите и trailer-ът са структура, не криптирано съдържание. Атакуващ не може да фалшифицира stream, но нищо в самия шифър не му пречи да пренареди към кои обекти сочи документът или да сглоби обекти от по-ранна ревизия на същия файл

Самостоятелният PDF MAC токен адресира точно този слой. PDFiumPas го извежда от ключа за криптиране на файла с посветен 32-байтов /KDFSalt, записан в Encrypt речника, така че притежанието на паролата е онова, което позволява на четец да потвърди токена. Резултатът е единствен отговор на единствен въпрос: дали този документ, като цяло, е документът, който е бил записан

var
  Pdf: TPdf;
  Mac: TPdfMacValidationResult;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.Password := 'open-secret';
    Pdf.FileName := 'quarterly-report.enc.pdf';
    Pdf.LoadDocument;

    Mac := Pdf.ValidatePdfMac('open-secret');
    case Mac.Status of
      pmvsValid:       ProcessDocument(Pdf);
      pmvsNotPresent:  ProcessWithWarning(Pdf);       // няма токен в този файл
      pmvsInvalid:     Quarantine(Mac.MessageText);   // подправен или отрязан
      pmvsUnsupported: RouteForManualReview(Mac.MessageText);
    end;
  finally
    Pdf.Free;
  end;
end;

Четирите статусни стойности изискват четири различни отговора, а свеждането им до булева стойност губи разграничението, което има значение. pmvsNotPresent означава, че файлът просто няма токен, което описва почти всеки криптиран PDF, записан преди 2024, и не е доказателство за нищо. pmvsInvalid означава, че токен присъства и не се проверява успешно, което е истинска находка и трябва да спре обработката. pmvsUnsupported означава, че токенът съществува във форма, която тази компилация не имплементира, което е пропуск в съвместимостта, не атака. Третирането на „не присъства“ като „невалиден“ би поставило под карантина целия ви архив в първия ден

Какво все още не прави криптирането

Флаговете за разрешения остават онова, което винаги са били: искане към съответстващ софтуер, не контрол. Битовете /P от Таблица 22 на ISO 32000-1, забраняващи печат или извличане, се спазват от добре възпитани зрители и се игнорират от всичко останало, а всеки, притежаващ потребителската парола, вече държи декриптираното съдържание. Криптирането е границата; разрешенията описват намерение вътре в нея

Два оперативни детайла си струва да се планират. Първо, криптирането и по-късна модификация си взаимодействат: добавянето на incremental update към криптиран документ има собствени правила, разгледани в incremental update-ите върху криптирани PDF, а MAC токен е декларация на ниво документ, която небрежно добавяне ще обезсили. Второ, GCM конструкцията използва детерминистичен IV брояч, а PDFiumPas хвърля изключение, вместо да повтори стойност на брояча, ако това пространство някога се изчерпи, защото повторение на nonce в GCM е катастрофално по начин, който тихо преливане би скрило

Диаграма на ревизиите на PDF криптиране R5, R6 и R7 и диапазоните на поддръжка при четци в PDFiumPas
R5 се отваря в петнайсет години четци, R6 е ISO 32000-2 по подразбиране, а R7 добавя AES-GCM със самостоятелен PDF MAC токен на цената на най-тясната поддръжка от четци

Избор между трите ревизии на практика

Запишете кой отваря файла, после изберете. За вътрешно разпространение, където всеки четец е текущ зрител под ваш контрол, R7 с integrity protection е най-силната налична опция и няма причина да не я използвате. За документи, напускащи организацията, R6 е защитимата стойност по подразбиране: тя е стандартизирана в ISO 32000-2, а не в техническа спецификация върху нея, а поддръжката е широка. За архиви и наследени потребители, R5 е единственият избор, който надеждно се отваря, и трябва да запишете защо на същото място, където записвате останалата част от политиката си за задържане

Диаграма, маршрутизираща четирите статусни стойности на ValidatePdfMac, връщани когато Delphi приложение отвори AESV4 криптиран PDF
ValidatePdfMac насочва четирите си token състояния към четири различни отговора, и само pmvsInvalid е доказателство за подправяне, докато pmvsNotPresent описва почти всеки шифрован PDF преди 2024

Каквото и да изберете, проверете изхода, вместо да се доверявате, че извикването е успяло. Отворете отново криптирания файл, проверете ValidatePdfMac и потвърдете, че декларираната версия е онова, което очаквате, използвайки проверките за съответствие на версия в точното съответствие на версия на PDF. По-широк списък за проверка на ненадеждни документи има в одита на рискове за сигурността на PDF

PDFiumPas е Delphi и Lazarus компонент около движока PDFium с изцяло нативно имплементиран в Pascal стек за криптиране на PDF 2.0, така че AES-256, GCM и MAC токенът не се нуждаят от външна крипто DLL. API-то за криптиране е документирано на страницата на PDFium компонента за Delphi