Erstellung und Dekodierung von CMS-Containern in Javascript
Das Projekt demonstriert die Umsetzung von Cryptographic Message Syntax über Javascript im Browser.
Web-Applikationen ersetzen zunehmend traditionelle Desktop-Applikationen. Dahingehend findet oftmals auch eine Verarbeitung sensibler Daten im Browser statt. Applikationen, die sicherheitskritische Daten verarbeiten, fehlen jedoch wichtige kryptographische Komponenten. Basiskomponenten wie RSA oder AES Verschlüsselung sind zwar mittlerweile ausreichend durch Javascript-Bibliotheken abgedeckt, jedoch werden keine darauf aufbauenden Bibliotheken beispielsweise zur Unterstützung von Cryptographic Message Syntax Containern angeboten. Im Zuge dieses Projektes wurde eine Basiskomponente entwickelt, die basierend auf bestehenden Kryptographie Bibliotheken eine Verschlüsselung und Entschlüsselung von Daten in CMS-Containern ermöglicht.
Als beispielhafte Anwendung von CMS-Funktionalität im Browser kann die Ablage von Dokumenten bei Cloud-Speichern wie beispielsweise Dropbox oder Google Drive genannt werden. Abbildung 1 skizziert eine mögliche Implementierung einer Web-Applikation zur Verschlüsselung und sicheren Ablage von Dokumenten. Dazu erfolgt die Verschlüsselung der Daten im Browser mit einem zufälligen, von der Applikation generierten symmetrischen Schlüssel (Content Encryption Key). Dieser wird mit dem öffentlichen RSA-Schlüssels des Empfängers bzw. der Empfänger des Dokuments verschlüsselt. Der von der Web-Applikation erstellte CMS-Container enthält somit die verschlüsselten Daten und den verschlüsselten Content Encryption Key. Eine Entschlüsselung kann nur mit dem privaten RSA-Schlüssel des bzw. der Empfänger erfolgen. Daraus ergibt sich, dass weder bei Angriffen auf den Cloud-Speicher noch durch direkten Zugriff des Cloud-Betreibers auf gespeicherte Daten ein Zugriff auf das entschlüsselte Dokument möglich ist.
Um die Voraussetzungen für den oben genannten Use Case zu erfüllen, wurde im Zuge dieses Projektes eine Javascript-Komponente implementiert, die das Erstellen und Parsen von CMS-Containern im Browser ermöglicht. Dabei werden die folgenden Schritte unterstützt:
- Erstellen von CMS-Containern
- Erstellung zufälliger AES-Schlüssel und AES-Verschlüsselung von Daten im Browser
- Erstellung des CMS-Containers (CMS ASN.1 Struktur)
- Parsen von CMS-Containern
- Parsen der ASN.1 Struktur von CMS-Containern
- Extraktion des verschlüsselten Content Encryption Key
- Extraktion der verschlüsselten Daten, verwendeten Algorithmen etc.
- Entschlüsseln der Daten mit entschlüsselten Content Encryption Key
Für die Verschlüsselung und Entschlüsselung des Content Encryption Key kommt eine Java-Anwendung zum Einsatz. Der dazu notwendige Java-Code kann als Basis für eine Implementierung bei einem serverseitigen Dienst zur Verwaltung von kryptographischen Schlüssel verwendet werden. Der zu verschlüsselnde oder zu entschlüsselnde Content Encryption Key wird Base64 kodiert mit der Java-Anwendung ausgetauscht.
Die entwickelte Basiskomponente verwendet, soweit möglich, bestehende Technologien. Konkret werden folgende Javascript-Bibliotheken verwendet:
- CryptoJS ist eine der gängigsten Javascript Crypto-Bibliotheken. Unter anderem bietet CryptoJS AES und DES Verschlüsselung, Unterstützung für die Berechnung von HMAC-Codes, eine Implementierung der PBKDF2 Funktion zur Schlüsselableitung und mehrere Hash-Algorithmen. Dieses Projekt verwendet CryptoJS für die AES Verschlüsselung und Entschlüsselung der Daten.
- jsrsasign bietet einen ASN.1 Encoder und vereinfacht somit die Erstellung von CMS-Containern. Zusätzlich unterstützt jsrsasign das Parsen von X.509 Zertifikaten und vereinfacht dadurch die Erstellung der ASN.1 Struktur IssuerAndSerialNumber.
- asn1js stellt einen ASN.1 Parser zur Dekodierung von DER oder BER kodierten ASN.1-Strukturen zur Verfügung und wird zum Parsen von CMS-Containern verwendet.
- jQuery wird für die DOM-Manipulation des implementierten Demonstrators verwendet. Zusätzlich findet das jQuery Base64 Plugin zur Kodierung und Dekodierung von Base64 Sequenzen Anwendung.
Einschränkungen
Die entwickelte Basiskomponente stellt keine vollständige CMS-Bibliothek dar sondern soll lediglich die Machbarkeit dieser demonstrieren. Nachfolgend werden Einschränkungen der implementierten Javascript-Komponente aufgelistet:
- Es wird lediglich der Typ EnvelopedData in Verbindung mit KeyTransRecipientInfos unterstützt.
- Als zusätzliche Einschränkung wird nur ein RecipientInfo Objekt pro CMS-Container unterstützt, eine Erweiterung auf mehrere RecipientInfo Objekte ist jedoch ohne große Probleme möglich.
- Die Verschlüsselung der Daten erfolgt in der momentanen Implementierung über AES im CBC Modus kann jedoch auf weitere Verschlüsselungsalgorithmen oder Modi erweitert werden.
- Die Verschlüsselung des Content Encryption Key erfolgt in einer zusätzlichen Java-Anwendung. Dabei ist ein manuelles Kopieren des verschlüsselten Schlüssels und anschließend des entschlüsselten Resultats notwendig. Sollten diese Operationen serverseitig z.B. unter Verwendung eines zentralen Schlüsselspeichers durchgeführt werden, kann der zur Verfügung gestellte Code weiterverwendet werden. Jedoch müsste dieser dazu um einen Mechanismus zum Matching des passenden Schlüssels anhand der Recipient Info erweitert werden.
- Momentan wird zur Schlüsselgenerierung die in CryptoJS verwendete Funktion Math.rand() verwendet. Math.random() kann jedoch nicht als kryptographisch starker Zufallszahlengenerator betrachtet werden. Bei Verwendung der entwickelten Basiskomponenten in einem Produktionsumfeld bzw. zur Verschlüsselung kritischer Daten, ist in jedem Fall auf Math.random() als Zufallszahlengenerator zu verzichten. Mögliche Alternativen sind beispielsweise die W3C Crypto API, Clipperz oder SJCL.
Links
Generell muss noch darauf hingewiesen werden, dass die Durchführung kryptographischer Operationen im Browser als problematisch angesehen werden kann. Für mehr Informationen werden folgende Beiträge empfohlen: