Techninis straipsnis

XLSX isvesties sifracija su AES Delphi: ką HotXLS SaveAsEncrypted rašo

Excel atskleidzia du dalykus, abu vadinamus "slaptažodžiu", ir tik vienas iš jų yra sifracija. Atidarymo slaptažodis rakina tikrą šifrą: be jo failas iš viso negali buti skaitytas. Darbalakio ir darbaknyges apsaugos slaptažodžiai nieko panasiaus nedaro. Jie nustato požymį, kuri bendradarbiaujantis redaktorius sutinka gerbti, ir darbaknyge, nesiojanti nieko kito kaip tik ta požymį, yra paprastas skaitomas zip su duomenimis, esanciais aiškiame tekste. Pasirinkite netinkamą ir siunciate atlyginimo duomenis, kurie atrodo užrakinti Excel ir skaitomi bet kokiame teksto redaktoriuje.

Įrodymas užtrunka dešimt sekundžių. Pervardykite apsaugotą .xlsx i .zip, atidarykite jį bet kuriame archyvų irankiuose ir pažiurekite xl/worksheets/sheet1.xml. Jei lasteleiu reiksmes yra aiškiame UTF-8, failas nera šifruotas, nesvarbu, kiek slaptažodžio raginimų Excel kelia, kai kas nors bando redaguoti lastelę. Ta spraga išlieka metus komandose, manančiose, kad lapo apsauga yra konfidencialumas, ir ji paprastai iškyla dieną, kai saugumo peržiūra vykdo tiksliai šį pervardijimą.

HotXLS yra gimtoji Delphi ir C++Builder skaiciuokliu biblioteka, ir ji laiko dvi funkcijas priešingose tos linijos pusėse. Darbalakio ir darbaknyges apsauga yra redagavimo apribojimai, paremti tycia silpnu sensojo maišo. SaveAsEncrypted sukuria AES-šifruotą paketą, kurio niekas be slaptažodžio neatidaro. Toliau esančiuose skyriuose aptariama, ką tas kvietimas rašo, asimetrija, kurią turite aplink projektuoti (HotXLS rašo šifruotus failus, bet negali jų skaityti atgal), ir kaip sensas XLS kelias skiriasi.

Kodel lapo apsauga nera sifracija

Metodai Protect ant lapų ir ProtectWorkbook ant darbaknyges saugo 4-šeštnainiu-skaitmenų maišą slaptažodžio. Tai yra sensoji algoritmas, kurį OOXML ir BIFF abu paveldejo iš 1990-uju Excel, ir formato dokumentacija niekada neteikia, kad jis daro daugiau nei sustabdo atsitiktinius redagavimus. Paketas lieka paprastu skaitomu zip: lasteleiu duomenys, formulės ir bendros eilutes visos aiškiame XML tekste. Numatytasis daro tai blogiau, o ne geriau. Kiekviena lastele prasideda su Locked=True, todel iškvietus Protect be anksčiau atrakinto ivesties diapazono sustingdo viso lapo redagavimą paliekant kiekvieną reiksmę aiškiai matomą.

Niekis to nedaro apsaugą nenaudinga. Vartotojų nukreipimas i redaguojamus diapazonus ir isdestymo stabilizavimas spausdinimui yra tikri darbai, aptarti mūsų straipsnyje apie darbalakio apsaugą ir puslapio konfigūraciją. Taciau tie yra naudojimo patirties darbai. Akimirka, kai reikalavimas yra konfidencialumas, vienintelis API, kuris i ji atsako, yra SaveAsEncrypted.

Ką SaveAsEncrypted iš tikruju rašo

Implementacija seka ECMA-376 Standard Encryption, apibrėžtą [MS-OFFCRYPTO] 2.3.4 skyriuje. Slaptažodis praeina 50 000 SHA-1 iteracijų išvesti AES-128 raktą. Verifikavimo blokas, šifruotas su AES-128 ECB rezimu, leidžia vartotojui patvirtinti slaptažodį pries bet ką iššifruojant, ir visas darbaknyges paketas tada yra šifruojamas su AES-128 CBC rezimu. Tai, kas atsiduria diske, visai nera zip. Tai yra OLE sudurtinis failas, laikantis EncryptionInfo, EncryptedPackage ir DataSpaces srautus, be xl/ katalogo, kurį archyvų irankis galetu išvardyti, ir štai kodėl pervardijimo tikrinimas dabar nieko skaitomo neranda. Excel 2007 ir vėlesnės versijos atidaro jį tik su slaptažodžiu, ir dabartinis LibreOffice taip pat skaito Standard Encryption.

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  rc: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Sheet := Book.Sheets.Add('Payroll');
    Sheet.Cells[1, 1].Value := 'Employee';
    Sheet.Cells[1, 2].Value := 'Net pay';
    Sheet.Cells[2, 1].Value := 'A. Garcia';
    Sheet.Cells[2, 2].Value := 4815.16;

    rc := Book.SaveAsEncrypted('payroll-2026-06.xlsx', PasswordFromVault);
    if rc <> 1 then
      raise Exception.CreateFmt('Encrypted save failed (rc=%d)', [rc]);
  finally
    Book.Free;
  end;
end;

Traktuokite slaptažodžio kintamąjį su tokia pacia priežiūra kaip ryšio eilutę. Gaukite jį iš saugyklos arba sukurto-slapto serviso paskutiniu momentu, niekada jo neregistruokite ir niekada jo nerašykite pačioje darbaknyge. Grazinimo kodo tikrinimas nera privalomas ceremonial. Šifravimo issaugojimas, kuris nepavyksta viduryje, turi nutraukti pristatymą, nes vienintelė atsarginė galimybė, kurią iškviečiamasis kodas gali pasiūlyti, yra nešifruota kopija, o ta kopija yra tiksliai incidentas, kuriam išvengti ši funkcija egzistuoja.

Taip pat yra mašinos patikrinamasis priėmimo tikrinimas, kainuojantis beveik nieko: iškvieskite CanReadEncrypted ant failo, kurį ką tik parašėte. Jis grazina true tik tada, kai išvestis iš tikrujų yra šifravimo konteineris, todel teigiant jį po kiekvieno šifruoto issaugojimo pagauna svarbiausia regresiją, kodo kelią, kuris tyliai grįžo prie paprasto SaveAs, akimirką, kai tai atsitinka, o ne savaites vėliau kliento gautuves. Galutinis žodis vis tiek priklauso rankiniam atidarymui Excel su tikruoju slaptažodžiu per leidimo testavimą.

Tik rašymui pagal dizainą: EXlsxEncryptionNotImplemented tvarkymas

Čia yra asimetrija, kuri turetu formuoti jūsų konvejerio architekturą: HotXLS šifruoja issaugojimo metu, taciau nedesifruoja atidarymo metu. OpenEncrypted iškelia EXlsxEncryptionNotImplemented, kai nukreipiamas i tikrą šifruotą paketą; ant paprasto darbaknyges jis tiesiog pereina i normalų Open. Kompanionas CanReadEncrypted aptinka OLE šifravimo konteinerį pigiai, todel priėmimo kodas gali nukreipti tokius failus netriggerinant išimties:

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.CanReadEncrypted(FileName) then
    begin
      // Encrypted container: HotXLS cannot decrypt it.
      Writeln(FileName + ': needs manual decryption in Excel first');
      Exit;
    end;
    try
      Book.OpenEncrypted(FileName, '');   // plain files fall through to Open
      Writeln(FileName + ': opened, ' + IntToStr(Book.Sheets.Count) + ' sheet(s)');
    except
      on EXlsxEncryptionNotImplemented do
        Writeln(FileName + ': encrypted - routed to manual queue');
    end;
  finally
    Book.Free;
  end;
end;

Ta asimetrija turi vieną aiškų architektūrinį skaitymą: šifruokite pristatymo krašte, paskutiniu. Laikykite paprastojo teksto originalą savo pasitikejimo riboje, duomenu bazėje, dokumentų saugykloje arba prieigos kontroliuojamoje bendrinamoje vietoje, ir sukurkite šifruotą kopiją kaip paskutinį žingsnį pries failo palikimą sistemą. Konvejeris, archyvuojantis tik šifruotą išvestį, užsirakino pats sau nuo savo duomenu, nes vėlesnė to paties sistemos stadija negali iš naujo atidaryti tų failų. Kai tolimesnis HotXLS procesas vėl reikia darbaknyges, perduokite jam paprastojo teksto originalą, niekada pristatymo artefaktą.

AES-128 Standard Encryption ir AES-256 atitikties linija

Office failu šifravimas ateina dviem kartomis. Standard Encryption, ta, kurią HotXLS rašo, naudoja AES-128 su SHA-1 rakto išvedimu. Agile Encryption atvyko vėliau ir pereina prie AES-256 su SHA-512 ir skirtingu, XML aprašytu rakto konteineriu. Abu atidaro skaidriai Excel, ir AES-128 vis dar yra skaiciuojamai patikimas failo apsaugai tranzitu klientui.

Skirtumas nustoja buti akademinis dieną, kai saugumo klausimynas prašo "AES-256 failu šifravimo ramybės vietoje." Standard Encryption neatitinka tos linijos, nesvarbu, koks stiprus yra slaptažodis, ir joks SaveAsEncrypted parametras nekeicia algoritmo, kurį jis issaugo. Todel tiksliai nustatykite profilį savo saugumo dokumentacijoje: AES-128, ECMA-376 Standard Encryption, SHA-1 rakto išvedimas 50 000 iteracijų. Reikalavimas, kuris isgyvena peržiūrą, yra vertas daugiau nei optimistinis, žlungantis audito metu.

Sensasis XLS kelias: RC4 išėjimui, RC4 ir XOR iejimui

BIFF fasadas turi priešingą formą. Jo šifravimas yra senesnis ir silpnesnis, taciau apvalus kelias yra pilnas: ką jis rašo, gali ir perskaityti atgal. Nustačius EncryptionPassword pries SaveAs sukuria RC4-šifruotą .xls per BIFF FilePass mechanizmą, ir Open su slaptažodžio parametru skaito visas tris sensosios schemos, RC4, RC4 CryptoAPI ir senovinį XOR užtemdymą:

var
  Writer, Reader: IXLSWorkbook;   // interface refs: no manual Free
begin
  Writer := TXLSWorkbook.Create;
  Writer.Sheets.Add.Cells.Item[1, 1].Value := 'Confidential';
  Writer.EncryptionPassword := 'S3cret!';
  Writer.SaveAs('confidential.xls');

  Reader := TXLSWorkbook.Create;
  if Reader.Open('confidential.xls', 'S3cret!') > 0 then
    Writeln(Reader.Sheets[1].Cells.Item[1, 1].Value);  // Entries are 1-based
end;

RC4 yra pasenusi kriptografija ir niekada neturetu saugoti šiandien svarbiu duomenu; vienintelė jo likusi vertė yra sąveikumas su sistemomis, vis dar keičianciomis .xls. Taciau skaitymo puse uzdirba savo vietą migracijos darbe. Slaptažodžiu apsaugoti sensojo formato failai atidaro su Open(FileName, Password), tiltas i OOXML modelį ir persaugoma per AES kelią, vienkryptinis atnaujinimas, veikiantis be Excel bet kurioje kilpoje. Didelio kiekio šifruotiems pristatymams, issaugojimo puses pralaidumo pastabos mūsų straipsnyje apie srauto rašymą serverio paketo darbams taikomos turinio kūrimo fazei, kuri vyksta pries šifravimą.

Sifracija ir apsauga nera varzetuvės

Dar vienas punktas, vertas atsiskaitymo, nes jis iškyla akimirką, kai kas nors šio puslapio pradžios perspėjimą skaito kaip "apsauga yra bevertė." Taip nėra. Šifravimas ir apsauga atsako skirtingus klausimus ir gražiai kaupiasi. Šifravimas sprendžia, kas gali atidaryti faila; apsauga sprendžia, ką skaitytojas, jau viduje esantis, gali keisti. Atlyginimo pristatymas pagrįstai gali daryti abu: šifruoti paketą, kad tik slaptažodžio turėtojas jį matytų, tada užrakinti formuliu lasteles, kad gavėjas galetu filtruoti ir rušiuoti, taciau tyliai nepers kaiciuotų. Klaida nera niekada prideti apsaugos. Klaida yra leisti jos buvimui atstovauti šifravimą, kai reikalavimas buvo konfidencialumas.

Saugojimo pusė neturi saugos tinklo, ir tai yra pagal dizainą. 50 000 iteracijų rakto išvedimas egzistuoja tam, kad spėjimas butų brangus, ir niekas failo viduje nesprendžia paslaptimi. Prarastas slaptažodis yra prarasti duomenys. Generuokite, pristatykite ir saugokite šiuos slaptažodžius su ta pacia drausme, kurią taikote duomenu bazės informacijai, ir šifravimas laikosi savo pusės.

Tikrasis failu šifravimas yra vienas kvietimas HotXLS. Drausmė gyvena viskame aplink kvietimą: slaptažodžio saugojimas, tik rašymo riba, neleidžianti HotXLS iš naujo atidaryti savo išvesties, ir algoritmo reikalavimas, kuri galite apginti audite. SaveAsEncrypted ir sensojo apvalio kelio pristatymo su HotXLS Component, vykdoma gimtai Delphi ir C++Builder procesuose be Excel automatizavimo bet kurioje kelyje.