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

Засичане на подправен XLSX: HotXLS Agile HMAC

HotXLS записва съответстващ блок dataIntegrity в Agile-криптирани XLSX пакети и го проверява при отваряне. HMAC-SHA-512 покрива целия EncryptedPackage stream, включително осембайтовия му StreamSize префикс, и се проверява върху ciphertext-а преди какъвто и да е сегмент да бъде декриптиран, така че грешна парола или променен пакет се засичат, вместо да се декриптират в боклук

Криптиране без цялостност е половин отговор, а форматите на Office файлове правят този пропуск лесен за подминаване, защото криптирането изглежда толкова задълбочено отвън. Разбирането какво обещава всеки слой е онова, което пази прегледа за сигурност кратък

Какво всъщност обещава криптирана книга?

Agile криптирането, дефинирано в [MS-OFFCRYPTO], дава конфиденциалност чрез AES в CBC режим с ключ, изведен от итеративен SHA-512 хеш на парола. Конфиденциалността е целият обещан резултат на тази конструкция. CBC не е authenticated режим: той не казва нищо за това дали ciphertext-ът, който декриптирате, е ciphertext-ът, който е бил записан

Практическото следствие е конкретно. Обърнете битове в криптиран пакет и CBC с готовност ще ги декриптира в различен plaintext. Обикновено ще получите грешка при парсване на ZIP някъде по-надолу, защото повреден deflate stream рядко оцелява, но „обикновено“ върши много работа в това изречение, а грешка от downstream parser е ужасно място да научите, че файл е бил променен. Елементът dataIntegrity съществува, за да отговори директно на въпроса, преди декриптиране, с MAC върху точните байтове

Как протича проверката и в какъв ред

Редът е интересната част. HotXLS извежда междинния ключ от паролата, декриптира криптирания HMAC ключ и HMAC стойността от атрибутите на dataIntegrity, използвайки IV-та, изведени от блоковия ключ, изчислява HMAC-SHA-512 върху криптирания пакет както е съхранен, и сравнява. Едва тогава започва декриптирането на сегменти

Проверяването на MAC-а върху ciphertext, а не върху plaintext, е стандартната дисциплина encrypt-then-MAC и точно тя прави проверката смислена: подправен пакет се отхвърля, без нито един контролиран от атакуващ байт да е бил прекаран през пътя на декриптиране и разгъване. И двете сравнения в пътя за отваряне — хешът на паролата за проверка и HMAC стойността — натрупват разлики чрез XOR и OR по целия дайджест, вместо да връщат резултат при първия несъвпаднал байт, така че нито едно от тях не изтича позиция на байт през timing

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    // Работи за обикновени, Standard-криптирани и Agile-криптирани файлове
    if Book.OpenEncrypted('incoming.xlsx', PasswordFromVault) = 1 then
      ProcessWorkbook(Book)
    else
      // Грешна парола или пакет, чийто dataIntegrity HMAC не е съвпаднал
      Quarantine('incoming.xlsx');
  except
    on E: Exception do
      Quarantine('incoming.xlsx: ' + E.Message);
  end;
  Book.Free;
end;

От страната на записа нищо не се променя във вашия код. SaveAsEncrypted излъчва блока автоматично, а солите, verifier входът и HMAC ключът идват от CryptGenRandom. Ако това извикване се провали, HotXLS хвърля изключение, вместо да премине към по-слаб източник. Fail-closed CSPRNG не е параноя; тихо понижаване към предвидим случаен източник произвежда файлове, които изглеждат криптирани, минават всеки функционален тест и са безполезни

Защо файлове без блока все пак се отварят?

Защото голямо количество Agile-криптирани книги в обращение са записани от производители, които пропускат dataIntegrity напълно, а отхвърлянето им би повредило далеч повече легитимна работа, отколкото би защитило. HotXLS третира цялостността като налична само когато и двата атрибута — криптираният HMAC ключ и криптираната HMAC стойност — присъстват и са добре оформени. В противен случай проверката се пропуска и файлът се отваря както преди

Това е решение за съвместимост с последствие за сигурността, което трябва изрично да назовете в собствения си модел на заплаха: отсъствието на блока не може да се разграничи от атакуващ, който го премахва, защото атрибутите са извън MAC-а, който биха носили. Ако контролирате двата края на конвейер, третирайте липсващ блок като провал на политика на ниво приложение. Ако приемате файлове от външния свят, третирайте проверката за онова, което е — ценен сигнал, когато присъства, и никакъв сигнал, когато отсъства

Парола за промяна е конвенция, не граница

Класическите XLS книги поддържат отделен механизъм, който рутинно се бърка с криптиране: резервацията за запис, известния прозорец на Excel „парола за промяна“. HotXLS го излага чрез SetModifyPassword, който приема паролата, флаг за препоръчано само за четене и името на резервиращия потребител, и докладва състоянието чрез IsWriteReserved. Подаването на празна парола изчиства резервацията

Онова, което се записва, е двойка записи WRITEPROT и FILESHARING, носещи флага за препоръчано само за четене, наследен 16-битов хеш на парола и потребителското име като BIFF8 Unicode низ. Този 16-битов хеш е контролна сума, не криптографски дайджест, а съдържанието на документа изобщо не е криптирано. Всеки, който отвори файла с друг инструмент, чете всичко. Реалната роля на функцията е координация: тя казва на следващия човек, че някой смята този файл за свой за редактиране, в същата категория като контролите на ниво лист, разгледани в XLSX защитата на лист и опциите allow

var
  Book: IXLSWorkbook;   // interface-с брояч на референции: не Free
begin
  Book := TXLSWorkbook.Create;
  if Book.Open('shared-model.xls') = 1 then
  begin
    // Препоръчано само за четене, резервирано от отчетната услуга
    Book.SetModifyPassword('edit-me', True, 'Reporting Service');

    if Book.IsWriteReserved then
      Book.SaveAs('shared-model.xls', xlExcel97);
  end;
end;

Използвайте двата слоя за онова, за което всеки е добър. Истинската конфиденциалност идва от SaveAsEncrypted с парола, която никой извън аудиторията не притежава, което произвежда AES-256 изхода, описан в AES-защитения XLSX изход. Резервацията за запис идва отгоре, когато книгата е споделен артефакт за редактиране и искате Excel да пита, преди някой да запише върху нея

Какво да проверите на ненадежден път за прием

Проверката на цялостността защитава криптирания полезен товар, не контейнера около него. XLSX файл е ZIP архив, а структурата на архива се парсва преди каквато и да е логика за криптиране да заработи, така че валидацията на ниво контейнер принадлежи първа във веригата; конкретните режими на провал са разгледани в валидацията на ZIP end-of-central-directory за ненадежден XLSX. След това третирайте провал на цялостността и грешна парола като едно и също оперативно събитие, защото от ваша страна те са неразличими по конструкция и и двете означават, че на файла не може да се вярва, че е онова, за което подателят го смята

Логвайте кои файлове изобщо са носили блок dataIntegrity. През няколко хиляди документа тази статистика ви казва нещо полезно за инструментите на подателите ви и превръща проверка по файл в наблюдение на ниво флот, върху което можете да действате

HotXLS чете и записва XLS, XLSX и ODS от Delphi и C++Builder без инсталация на Excel, имплементирайки пътищата за Standard и Agile криптиране от [MS-OFFCRYPTO] в Pascal. API-тата за криптиране, защита и книги са документирани на страницата на HotXLS Delphi компонента за електронни таблици