Πώς να δημιουργήσετε μια κρυπτογραφική ισομορφική βιβλιοθήκη με Javascript και WebAssembly

Ας το παραδεχτούμε: αγαπάμε μυστικά. Μοιραζόμαστε μυστικά με τους καλύτερους φίλους μας, κρατάμε μυστικά από τους γονείς μας και γράφουμε μυστικά περιοδικά για να τους πούμε τις βαθύτερες σκέψεις μας. Κατά τη διάρκεια των αιώνων, αυτή η φυσική κλίση εξελίχθηκε από τη θορυβία ορισμένων μαθηματικών σε μια πραγματική επιστήμη που διδάσκεται στα πανεπιστήμια σε όλο τον κόσμο. Στο παρελθόν, η τέχνη της διατήρησης μυστικών που τώρα ονομάζουμε κρυπτογραφία χρησίμευε σχεδόν αποκλειστικά για την ιδιωτική ανταλλαγή πληροφοριών μεταξύ των χωρών. Στο παρόν, είναι πανταχού παρόν.

"Ο κόσμος τρέχει με κώδικες και κρυφές ψηφίδες, John. Από το σύστημα ασφαλείας των εκατομμυρίων λιβρών στην τράπεζα μέχρι το μηχάνημα Pin έχετε κάνει εξαίρεση. Η κρυπτογραφία κατοικεί σε κάθε στιγμή της αφύπνισης μας "- Sherlock Holmes

Με την έλευση του Διαδικτύου, στην πραγματικότητα, η ιδιωτικότητα έχει γίνει πρωταρχικό μέλημα. Κατά τη διάρκεια του Β 'Παγκοσμίου Πολέμου, τα μηχανήματα Enigma ήταν κρίσιμα για τον προσδιορισμό του θριάμβου και της ήττας της Γερμανίας. Αλλά στην εποχή του διαδικτύου, οι πληροφορίες είναι εγγενώς ψηφιακές και κάθε ηλεκτρονικός υπολογιστής είναι ένα υπερσύγχρονο μηχάνημα Enigma. Δεν προκαλεί έκπληξη το γεγονός ότι έχουμε εγκλωβίσει την επιθυμία μας για μυστικότητα στον κώδικα, αναθέτοντας στα ίδια τα συστήματα ηλεκτρονικών υπολογιστών να κρατούν μυστικά για λογαριασμό μας. Η τέχνη της μυστικότητας δεν είναι τίποτα περισσότερο για την κλοπή κυπρίων από τον τομέα του εχθρού. Πρόκειται μάλλον για την κατασκευή μηχανών που είναι σε θέση να επικοινωνούν μεταξύ τους χωρίς να αποκρυπτογραφεί το μήνυμα από τρίτο μέρος. Σήμερα, η κρυπτογραφία έχει καταστεί ένα απαραίτητο εργαλείο για την προστασία των πληροφοριών: ο τραπεζικός μας λογαριασμός, τα ηλεκτρονικά μας μηνύματα, οι συνήθειες περιήγησης στο διαδίκτυο, όλες ασφαλίζονται με κρυπτογραφία. Το εύρος των εφαρμογών είναι τεράστιο. Η κρυπτογραφική επικοινωνία χρησιμοποιείται για την ιδιωτική ανταλλαγή μηνυμάτων από απόσταση μιλίων σε λίγα μόνο δευτερόλεπτα, αλλά και για την ασφαλή αποθήκευση δεδομένων προσωπικού χαρακτήρα που μπορούσαμε να διαβάσουμε μόνοι μας. Στον σύγχρονο κόσμο, η κρυπτογραφία είναι η κόλλα που κρατά τον κόσμο συνδεδεμένο.

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

Η αναζήτηση για το Άγιο Δισκοπότηρο στις κρυπτογραφικές βιβλιοθήκες Ιστού

Εδώ στο Cubbit έχουμε το όνειρο της αποκέντρωσης της υποδομής δεδομένων και για το σκοπό αυτό χρειαζόμαστε μια εφαρμογή στο διαδίκτυο στην οποία οι χρήστες μπορούν να σώζουν και να έχουν πρόσβαση στα αρχεία τους από οπουδήποτε στον κόσμο. Αυτός είναι ο λόγος για τον οποίο ξεκινήσαμε την αναζήτησή μας για διαθέσιμες κρυπτογραφικές βιβλιοθήκες Ιστού που εκτελούνται στο πρόγραμμα περιήγησης. Παρόλο που πολλά από αυτά εμφανίστηκαν κατά τη διάρκεια των ετών, κανείς δεν ταιριάζει στις ανάγκες μας όσον αφορά την ταχύτητα κρυπτογράφησης και τη χρηστικότητα για τρεις κύριους λόγους:

  • Υπερβολικά περίπλοκα API.
  • Κακές επιδόσεις κατά την κρυπτογράφηση / αποκρυπτογράφηση αρχείων (η κρυπτογραφία είναι μια υπολογιστική εντατική εφαρμογή και έχει τυπικά εκτελεστεί ελάχιστα στη Javascript).
  • Έλλειψη προτύπων που χρειαζόμαστε για να οικοδομήσουμε την κρυπτο αρχιτεκτονική μας.

Λόγος # 0: οι βιβλιοθήκες crypto web είναι άγριες

Ας εξερευνήσουμε τους λόγους αυτούς σε βάθος.

Πρώτον, υποθέτουμε ότι το OpenSSL είναι το de facto κρυπτογραφικό πρότυπο, δεδομένου ότι πολλές εταιρείες το υιοθετούν στη ροή εργασιών ασφαλείας τους. Ωστόσο, δεδομένου ότι γράφτηκε στο C, φέρει φοβερές υπογραφές API και εξακολουθεί να είναι ελάχιστα τεκμηριωμένη, καθιστώντας την καμπύλη μάθησης πιο απότομη από άλλες τεχνολογίες. Έτσι, όλες οι αναδυόμενες βιβλιοθήκες crypto προσπαθούν να διατηρήσουν το codebase τους συμβατό με το OpenSSL όσο το δυνατόν, με αποτέλεσμα να μην απλοποιήσουν το API τους για νέους προγραμματιστές.

Λόγος # 1: η κρυπτογράφηση στον ιστό είναι ανασφαλής και αργή

Δεύτερον, η εξέλιξη των τεχνολογιών Ιστού έχει ως αποτέλεσμα οι browser να υιοθετούν μόνο Javascript για λόγους απλότητας. Παρ 'όλα αυτά, το Javascript δεν είναι η καλύτερη γλώσσα για υπολογιστικές βαριές εργασίες και μαντέψτε τι, η κρυπτογραφία είναι μια υπολογιστική βαριά εργασία. Επίσης, δεδομένης της συνεχώς αυξανόμενης υιοθέτησής του, είναι συχνά η πρώτη επιλογή από πολλούς εκκολαπτόμενους προγραμματιστές στην πρώτη τους εμπειρία. Αποτέλεσμα: πολλοί από αυτούς άρχισαν να γράφουν κακό κώδικα, καθιστώντας τη γλώσσα γεμάτη θέματα ασφάλειας.

Λόγος # 2: έλλειψη υποστήριξης για τα ECC και άλλα πρότυπα σε πολλές βιβλιοθήκες

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

Ας αρχίσουμε

Για να ξεπεράσουμε όλα αυτά τα προβλήματα, ξεκινήσαμε την ανάπτυξη της βιβλιοθήκης κρυπτογράφησης στο σπίτι. Σχεδιάσαμε αυτό με τρεις ξεκάθαρους στόχους:

  1. Ισομορφισμός
  2. Ταχύτητα κρυπτογράφησης αρχείων
  3. Ποτέ μην επανεφεύρετε τον τροχό εκτός αν είναι τετράγωνο

Ο ισομορφισμός αναφέρεται στην έννοια του καθολικού κώδικα, δηλ. Γράφει μία φορά, τρέχει οπουδήποτε.

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

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

Στο δίκτυο

Ξοδέψαμε ώρες και ώρες (επαν) αναζητώντας μια βιβλιοθήκη με τα χαρακτηριστικά και τις επιδόσεις που χρειαζόμασταν χωρίς επιτυχία. Έτσι αποφασίσαμε να δοκιμάσουμε το μονοπάτι της σύνταξης.

Τι? Σύνταξη Javascript; Πως?

Χάρη στην Emscripten!

Το Emscripten είναι μια αρκετά νέα τεχνολογία με κάποια πολύ ενδιαφέρουσα αξίωση, αναφέροντας:

Το Emscripten είναι μια εργαλειομηχανή για τη σύνταξη σε asm.js και WebAssembly, που είναι κατασκευασμένα με LLVM, που σας επιτρέπει να εκτελέσετε C και C ++ στον ιστό με σχεδόν εγγενή ταχύτητα χωρίς plugins.

Αξίζει να δοκιμάσετε, δεν σκέφτεστε;

Ξεκινήσαμε από την εφαρμογή ED25519. Το Emscripten έχει τη δική του βιβλιοθήκη που πρέπει να συμπεριληφθεί στις συνδέσεις.

Ένα σημαντικό θέμα είναι η διαχείριση της μνήμης. Στον κόσμο Javascript, εμείς, ως προγραμματιστές, χρησιμοποιούμε για να πιστεύουμε στον μεγαλύτερο συλλέκτη σκουπιδιών που μας επιτρέπει να αγνοούμε απλά κάθε πτυχή που σχετίζεται με τη μνήμη. Αλλά για να χρησιμοποιήσουμε επιτυχώς τον κώδικα Emscripten, αναγκάζαμε να φροντίσουμε την κοινή μνήμη με malloc και δωρεάν.

const heap_seed = em_array_malloc ((εαυτός ως οποιοδήποτε) .enigma, σπόρος);
ED25519.create_keypair (heap_seed.byteOffset, seed.length);
em_array_free ((ως εαυτούς) .enigma, heap_seed);

Με αυτό το αποτέλεσμα εργασίας στην τσάντα, μετακινήσαμε σε ένα άλλο θέμα: AES streaming mode. Δεν βρήκαμε πολύ καλές επιδόσεις κατά τη διάρκεια της έρευνάς μας και έτσι επιλέγουμε να δοκιμάσουμε το OpenSSL. Αυτό σήμαινε ότι ο κώδικας βάσης έπρεπε να συνταχθεί με το Emscripten. δυστυχώς, ωστόσο, έλλειπε τεκμηρίωση. Έτσι, μετά από μερικές φορές, βρήκαμε εμπειρικά τη διαδικασία για την επίτευξη των αποτελεσμάτων,

δηλαδή τα ακόλουθα βήματα:

  1. Αποκλείστε όλους τους κρυπτογράφους που δεν απαιτούνται αυστηρά
  2. Cross-compile
  3. Συνδέστε τον κώδικα σας

Και…

Στο Node.js

Το typescript, το δακτυλογραφημένο υπερβατήριο της Javascript από τη Microsoft, είναι η εστία της τεχνολογικής στοίβας εδώ στο Cubbit. Έτσι θα ήταν φυσικό να οικοδομήσουμε την κρυπτογραφική στοίβα και στο Typescript. Ωστόσο, οι επιδόσεις και η κρυπτογραφία ταιριάζουν απόλυτα με τις μητρικές γλώσσες όπως η C ++, ενώ, όπως είπαμε, το Typescript είναι ακατάλληλο για την εργασία.

Έτσι αποφασίσαμε να πάμε με το Node.js ως πρωτεύουσα γλώσσα, καθώς μας επιτρέπει να χρησιμοποιούμε τα πρόσθετα για την εύκολη ενσωμάτωση του εγγενούς κώδικα. Από αυτή την άποψη, το N-API είναι ένα εξαιρετικό εργαλείο από την ομάδα Node.js, ένα API που είναι σταθερό σε όλες τις εκδόσεις Node.js: δημιουργήστε μόνο μία φορά και θα τρέξει σε κάθε μεταγενέστερη μεγάλη έκδοση χωρίς recompilation.

Επιπλέον, είναι επίσης πολύ απλό στη χρήση:

Απλά περιστρέψτε και εξαγάγετε τα αντικείμενα και τις λειτουργίες που θέλετε να μοιραστείτε με τον κόσμο Javascript και αφήστε τον μεταγλωττιστή να κάνει τη σκληρή δουλειά για σας.

Enigma, μια γρήγορη παγκόσμια βιβλιοθήκη κρυπτογράφησης

Και έτσι, μετά από μερικούς μήνες έρευνας και κωδικοποίησης, το Enigma είχε έρθει στη ζωή.

Το Enigma είναι μια βιβλιοθήκη κρυπτογράφησης που έχει σχεδιαστεί για να εργάζεται αποτελεσματικά σε προγράμματα περιήγησης χρησιμοποιώντας μοχθηρές τεχνολογίες όπως WebCrypto και WebAssembly. Στόχος μας είναι να παρέχουμε τους βασικούς κρυπτογραφικούς αλγόριθμους καθώς και μια σουίτα υπηρεσιών κοινής ωφέλειας για την απλοποίηση της χρήσης στον "πρότυπο" προγραμματιστή.

Για να διευκολυνθεί περαιτέρω η υιοθέτησή του, κάναμε το Enigma ισομορφικό, δηλ. Συμβατό τόσο με το Node.js όσο και με το Διαδίκτυο ώστε να το καταστήσει διαλειτουργικό χωρίς να αλλάξει μια γραμμή κώδικα. Ο κώδικας πρέπει να είναι καθολικός, σύμφωνα με το σύνθημα WORA, δηλαδή "γράψτε μία φορά, τρέξτε οπουδήποτε".

Πως να το χρησιμοποιήσεις

Τώρα μπορείτε να πείτε: "Εντάξει, δροσερό! Αλλά πώς μπορώ να το χρησιμοποιήσω; "Πρώτα από όλα, θα πρέπει να το εγκαταστήσετε. Όντας Enigma μια μονάδα NPM, μπορείτε απλά να πληκτρολογήσετε την ακόλουθη εντολή στο τερματικό σας:

npm install @ cubbit / enigma

ή αν προτιμάτε νήματα:

νήματα add @ cubbit / enigma

Τώρα το Enigma είναι εγκατεστημένο και μέρος των εξαρτήσεων σας.

Ήρθε η ώρα να αρχίσετε να το χρησιμοποιείτε στη συνέχεια!

Ας υποθέσουμε ότι θέλετε να κρυπτογραφήσετε ένα μήνυμα με AES-256 (για να ξεκινήσετε εύκολα). Ορίστε. Πρώτον, πρώτα πρέπει να αρχικοποιήσουμε το Enigma. Δεδομένου ότι χρησιμοποιεί τον εγγενή κώδικα για να ενισχύσει την απόδοση, πρέπει να περιμένουμε το πρόγραμμα περιήγησης να το φορτώσει πριν μπορέσουμε να χρησιμοποιήσουμε τη βιβλιοθήκη.

ΣΗΜΕΙΩΣΗ: Ο ακόλουθος κώδικας είναι γραμμένος σε Typescript, αλλά μπορείτε επίσης να γράψετε καθαρά Javascript φυσικά!

Ο στόχος μας εδώ είναι να κρυπτογραφήσουμε μια απλή συμβολοσειρά κειμένου.

Προσέξτε ότι, δεδομένου ότι ο AES256 είναι συμμετρικός αλγόριθμος κρυπτογράφησης, πρέπει να χρησιμοποιήσουμε το ίδιο κλειδί που χρησιμοποιήσαμε για την κρυπτογράφηση του μηνύματος για να το αποκρυπτογραφήσουμε. Κάτι όπως:

Ας υποθέσουμε ότι τώρα θέλουμε να κρυπτογραφήσουμε ένα αρχείο πριν το αποστείλουμε στο δίκτυο. Λοιπόν, πρέπει να ξέρετε ότι τα περισσότερα από τα υπάρχοντα προγράμματα περιήγησης έχουν περιορισμούς όσον αφορά τη μέγιστη μνήμη που μπορεί να διατεθεί από μια ιστοσελίδα. Για παράδειγμα, το Google Chrome μπορεί να διαθέτει μέγιστη μνήμη RAM 1,5 GB. Επίσης, γενικά, οι αλγόριθμοι κρυπτογράφησης μπλοκ λειτουργούν καλύτερα με μικρά κομμάτια δεδομένων. Κατά συνέπεια, δεν συνιστάται η κρυπτογράφηση ολόκληρου του αρχείου, αλλά η κρυπτογράφηση του προοδευτικά. Σε αυτό το πεδίο, το Node.js παρέχει ένα πολύ βολικό και καλά σχεδιασμένο εργαλείο για το χειρισμό ροών δεδομένων: το αντικείμενο Stream. Έχουμε λοιπόν την έμπνευση από αυτό για να παρέχουμε ένα απλό API.

Η ισχύς αυτού του είδους της σύνταξης είναι ότι μπορείτε να συνδέσετε τους σωλήνες μαζί για να στέλνετε αυτόματα το κρυπτογραφημένο αρχείο μέσω του δικτύου ενώ είναι κρυπτογραφημένο. Μαγεία! :)

file_stream.pipe (aes_stream) .pipe (υποδοχή);

Το Enigma προσφέρει πολλά ακόμα χαρακτηριστικά, οπότε αν ενδιαφέρεστε, μπορείτε να επισκεφτείτε το χώρο αποθήκευσης και να συμβάλλετε.

Τα αποτελέσματα

Εκτελούμε μια δέσμη σημείων αναφοράς για να συγκρίνουμε το Enigma με άλλες υπάρχουσες βιβλιοθήκες για τον ιστό. Εδώ είναι τα αποτελέσματα (Chrome 72 στο I7-7820HQ - χαμηλότερο είναι καλύτερο):

AES κρυπτογράφηση. Κάτω είναι καλύτερη

Όπως μπορείτε να δείτε, το Enigma λειτουργεί καλύτερα όταν κρυπτογραφεί και επεξεργάζεται αρχεία αντί να κρυπτογραφεί μικρές χορδές. Στην πραγματικότητα, εισάγουμε μια μικρή επιβάρυνση φορτώνοντας τα δυαδικά αρχεία συναρμολόγησης ιστού, αλλά αλλάζει το παιχνίδι όταν πρέπει να κρυπτογραφήσουμε μεγαλύτερο όγκο δεδομένων, όπως αρχείων.

Το όραμά μας για το μέλλον του Enigma

Στόχος μας είναι να δημιουργήσουμε μια κρυπτογραφική βιβλιοθήκη τόσο ισχυρή όσο και απλή.

Θα συνεχίσουμε να περιβάλλουμε τις βιβλιοθήκες με τα API μας για να εφαρμόσουμε περισσότερους αλγόριθμους και να επιτύχουμε καλύτερες επιδόσεις. Έχουμε σχεδιάσει το Enigma με γνώμονα τη χρηστικότητα και τις επιδόσεις και θα συνεχίσουμε να εργαζόμαστε για να το βελτιώσουμε.

ΥΣΤΕΡΟΓΡΑΦΟ. Το αίνιγμα έχει αναπτυχθεί ως το κρυπτογραφικό στρώμα για το Cubbit, το οποίο ξεκινάει τώρα το κατανεμημένο σύννεφο του. Αν θέλετε να μάθετε περισσότερα, ελέγξτε το εδώ.