Τεχνικό Άρθρο

Εντοπισμός Παραποίησης XLSX: HotXLS Agile HMAC

Το HotXLS γράφει ένα συμβατό block dataIntegrity σε πακέτα XLSX κρυπτογραφημένα με Agile και το επαληθεύει κατά το άνοιγμα. Το HMAC-SHA-512 καλύπτει ολόκληρο το stream EncryptedPackage, συμπεριλαμβανομένου του οκταψήφιου προθέματος StreamSize, και ελέγχεται πάνω στο ciphertext πριν αποκρυπτογραφηθεί οποιοδήποτε τμήμα, ώστε ένας λανθασμένος κωδικός πρόσβασης ή ένα τροποποιημένο πακέτο να εντοπίζεται αντί να αποκρυπτογραφείται σε ακαταλαβίστικα δεδομένα

Η κρυπτογράφηση χωρίς ακεραιότητα είναι μισή απάντηση, και οι μορφές αρχείων Office κάνουν αυτό το κενό εύκολο να παραβλεφθεί επειδή η κρυπτογράφηση φαίνεται τόσο πλήρης απ' έξω. Το να κατανοείτε τι υπόσχεται κάθε επίπεδο είναι αυτό που κρατά μια αναθεώρηση ασφάλειας σύντομη

Τι υπόσχεται στην πραγματικότητα ένα κρυπτογραφημένο βιβλίο εργασίας;

Η κρυπτογράφηση Agile, όπως ορίζεται στο [MS-OFFCRYPTO], σας δίνει εμπιστευτικότητα μέσω AES σε λειτουργία CBC με κλειδί που προκύπτει από επαναλαμβανόμενο hash κωδικού πρόσβασης SHA-512. Η εμπιστευτικότητα είναι όλη η υπόσχεση αυτής της κατασκευής. Το CBC δεν είναι authenticated mode: δεν λέει τίποτα για το αν το ciphertext που αποκρυπτογραφείτε είναι το ciphertext που γράφτηκε

Η πρακτική συνέπεια είναι συγκεκριμένη. Αναστρέψτε bits σε ένα κρυπτογραφημένο πακέτο και το CBC θα τα αποκρυπτογραφήσει ευχαρίστως σε διαφορετικό plaintext. Συνήθως θα πάρετε ένα σφάλμα ανάλυσης ZIP κάπου παρακάτω, επειδή ένα κατεστραμμένο deflate stream σπάνια επιβιώνει, αλλά το "συνήθως" κάνει πολλή δουλειά σε αυτή την πρόταση, και ένα σφάλμα κατάντη parser είναι ένα απαίσιο σημείο για να μάθετε ότι ένα αρχείο τροποποιήθηκε. Το στοιχείο dataIntegrity υπάρχει για να απαντήσει απευθείας στο ερώτημα, πριν την αποκρυπτογράφηση, με ένα MAC πάνω στα ακριβή bytes

Πώς τρέχει ο έλεγχος, και με ποια σειρά

Η σειρά είναι το ενδιαφέρον σημείο. Το HotXLS παράγει το ενδιάμεσο κλειδί από τον κωδικό πρόσβασης, αποκρυπτογραφεί το κρυπτογραφημένο κλειδί HMAC και την κρυπτογραφημένη τιμή HMAC από τα attributes του dataIntegrity χρησιμοποιώντας IVs που προκύπτουν από block key, υπολογίζει HMAC-SHA-512 πάνω στο πακέτο όπως είναι αποθηκευμένο, και συγκρίνει. Μόνο τότε ξεκινά η αποκρυπτογράφηση τμημάτων

Ο έλεγχος του MAC πάνω στο ciphertext αντί στο plaintext είναι η τυπική πειθαρχία encrypt-then-MAC, και είναι αυτό που κάνει τον έλεγχο ουσιαστικό: ένα παραποιημένο πακέτο απορρίπτεται χωρίς κανένα byte ελεγχόμενο από επιτιθέμενο να έχει περάσει καν από τη διαδρομή αποκρυπτογράφησης και αποσυμπίεσης. Και οι δύο συγκρίσεις στη διαδρομή ανοίγματος, το hash verifier κωδικού πρόσβασης και η τιμή HMAC, συσσωρεύουν διαφορές με XOR και OR σε ολόκληρο το digest αντί να επιστρέφουν νωρίς στο πρώτο byte που δεν ταιριάζει, οπότε καμία δεν διαρρέει θέση byte μέσω timing

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    // Λειτουργεί για απλά, Standard-encrypted και Agile-encrypted αρχεία
    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 εκπέμπει το block αυτόματα, και τα salts, η είσοδος verifier και το κλειδί HMAC προέρχονται από την CryptGenRandom. Αν αυτή η κλήση αποτύχει, το HotXLS εγείρει εξαίρεση αντί να επιστρέφει σε ασθενέστερη πηγή. Ένα fail-closed CSPRNG δεν είναι παρανοϊκότητα· μια σιωπηλή υποβάθμιση σε προβλέψιμη τυχαία πηγή παράγει αρχεία που φαίνονται κρυπτογραφημένα, περνούν κάθε λειτουργικό τεστ, και δεν αξίζουν τίποτα

Γιατί αρχεία χωρίς το block ανοίγουν ακόμη;

Επειδή πολλά Agile-encrypted βιβλία εργασίας σε κυκλοφορία γράφτηκαν από παραγωγούς που παραλείπουν εντελώς το dataIntegrity, και η απόρριψή τους θα έσπαγε πολύ περισσότερη νόμιμη δουλειά απ' όση θα προστάτευε. Το HotXLS αντιμετωπίζει την ακεραιότητα ως παρούσα μόνο όταν και τα δύο attributes, το κρυπτογραφημένο κλειδί HMAC και η κρυπτογραφημένη τιμή HMAC, υπάρχουν και είναι καλά σχηματισμένα. Διαφορετικά η επαλήθευση παραλείπεται και το αρχείο ανοίγει όπως πριν

Αυτή είναι μια απόφαση συμβατότητας με μια συνέπεια ασφάλειας που πρέπει να ονομάσετε ρητά στο δικό σας μοντέλο απειλής: η απουσία του block δεν μπορεί να διακριθεί από την αφαίρεσή του από έναν επιτιθέμενο, επειδή τα attributes βρίσκονται εκτός του MAC που θα τα κάλυπτε. Αν ελέγχετε και τα δύο άκρα ενός pipeline, αντιμετωπίστε ένα απόν block ως αποτυχία πολιτικής σε επίπεδο εφαρμογής. Αν δέχεστε αρχεία από τον κόσμο, αντιμετωπίστε τον έλεγχο για αυτό που είναι, ένα πολύτιμο σήμα όταν υπάρχει και κανένα σήμα καθόλου όταν απουσιάζει

Ο κωδικός τροποποίησης είναι σύμβαση, όχι όριο

Τα κλασικά βιβλία εργασίας XLS υποστηρίζουν έναν ξεχωριστό μηχανισμό που συχνά συγχέεται με την κρυπτογράφηση: το write reservation, η προτροπή "password to modify" του Excel. Το HotXLS το εκθέτει μέσω της SetModifyPassword, που δέχεται τον κωδικό πρόσβασης, μια σημαία recommend-read-only και το όνομα του χρήστη που κάνει την κράτηση, και αναφέρει την κατάσταση μέσω της IsWriteReserved. Περνώντας κενό κωδικό πρόσβασης εκκαθαρίζεται η κράτηση

Αυτό που γράφεται είναι ένα ζεύγος εγγραφών WRITEPROT και FILESHARING που φέρουν τη σημαία recommend-read-only, ένα παλαιό 16-bit hash κωδικού πρόσβασης και το όνομα χρήστη ως BIFF8 Unicode string. Αυτό το 16-bit hash είναι ένα checksum, όχι ένα κρυπτογραφικό digest, και το περιεχόμενο του εγγράφου δεν κρυπτογραφείται καθόλου. Όποιος ανοίξει το αρχείο με οποιοδήποτε άλλο εργαλείο διαβάζει τα πάντα. Η πραγματική δουλειά του χαρακτηριστικού είναι ο συντονισμός: λέει στον επόμενο ότι κάποιος θεωρεί αυτό το αρχείο δικό του προς επεξεργασία, στην ίδια κατηγορία με τους ελέγχους επιπέδου φύλλου που καλύπτονται στο προστασία φύλλου XLSX και επιλογές allow

var
  Book: IXLSWorkbook;   // interface-counted: μην κάνετε Free
begin
  Book := TXLSWorkbook.Create;
  if Book.Open('shared-model.xls') = 1 then
  begin
    // Recommend read-only, κρατημένο από την υπηρεσία αναφορών
    Book.SetModifyPassword('edit-me', True, 'Reporting Service');

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

Χρησιμοποιήστε και τα δύο επίπεδα για ό,τι κάνει καλά το καθένα. Η πραγματική εμπιστευτικότητα προέρχεται από την SaveAsEncrypted με κωδικό πρόσβασης που κανείς εκτός κοινού δεν κατέχει, κάτι που παράγει την έξοδο AES-256 που περιγράφεται στο έξοδος XLSX προστατευμένη με AES. Το write reservation μπαίνει από πάνω όταν το βιβλίο εργασίας είναι ένα κοινόχρηστο αντικείμενο επεξεργασίας και θέλετε το Excel να ρωτήσει πριν κάποιος αποθηκεύσει πάνω του

Τι να ελέγξετε σε ένα μη έμπιστο μονοπάτι εισαγωγής

Η επαλήθευση ακεραιότητας προστατεύει το κρυπτογραφημένο payload, όχι το container γύρω του. Ένα αρχείο XLSX είναι ένα αρχείο ZIP, και η δομή του αρχείου αναλύεται πριν τρέξει καμία λογική κρυπτογράφησης, οπότε η επικύρωση σε επίπεδο container ανήκει πρώτη στην αλυσίδα· οι συγκεκριμένοι τρόποι αποτυχίας καλύπτονται στο επικύρωση ZIP end-of-central-directory για μη έμπιστα XLSX. Μετά από αυτό, αντιμετωπίστε μια αποτυχία ακεραιότητας και έναν λανθασμένο κωδικό πρόσβασης ως το ίδιο επιχειρησιακό συμβάν, επειδή από τη δική σας πλευρά είναι εξ ορισμού αδιάκριτα, και και τα δύο σημαίνουν ότι το αρχείο δεν μπορεί να θεωρηθεί αξιόπιστο ως αυτό που ο αποστολέας νομίζει

Καταγράψτε ποια αρχεία έφεραν καθόλου block dataIntegrity. Σε μερικές χιλιάδες έγγραφα αυτό το στατιστικό σας λέει κάτι χρήσιμο για τα εργαλεία των αποστολέων σας, και μετατρέπει έναν έλεγχο ανά αρχείο σε μια παρατήρηση σε επίπεδο στόλου την οποία μπορείτε να αξιοποιήσετε

Το HotXLS διαβάζει και γράφει XLS, XLSX και ODS από Delphi και C++Builder χωρίς εγκατεστημένο Excel, υλοποιώντας τις διαδρομές κρυπτογράφησης Standard και Agile του [MS-OFFCRYPTO] σε Pascal. Τα API κρυπτογράφησης, προστασίας και βιβλίου εργασίας τεκμηριώνονται στη σελίδα του HotXLS Delphi spreadsheet component