Flexible Anbindung von Smartcards an eine
Transcription
Flexible Anbindung von Smartcards an eine
Fachbereich Informatik Fachgebiet Theoretische Informatik Prof. Dr. Johannes Buchmann Flexible Anbindung von Smartcards an eine Sicherheitsinfrastruktur Diplomarbeit von Maryia Drahavets Betreuer: Evangelos Karatsiolis 2. August 2006 ii Loka Samasta Sukhino Bhavantu Mögen alle Wesen Glück und Harmonie erreichen iv Ehrenwörtliche Erklärung Hiermit versichere ich, die vorliegende Diplomarbeit ohne Hilfe Dritter und nur mit den angegebenen Quellen und Hilfsmitteln angefertigt zu haben. Alle Stellen, die aus den Quellen entnommen wurden, sind als solche kenntlich gemacht worden. Diese Arbeit hat in gleicher oder ähnlicher Form noch keiner Prüfungsbehörde vorgelegen. Darmstadt, August 2006 Maryia Drahavets m.drahavets@web.de v vi Inhaltsverzeichnis 1 Einleitung 1 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Aufgabenstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.3 Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 Grundlagen 2.1 2.2 2.3 5 Public-Key-Kryptographie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.1 Public-Key-Verschlüsselung . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.2 Digitale Signaturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Public-Key-Infrastruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2.1 Persönliche Sicherheitsumgebung . . . . . . . . . . . . . . . . . . . . 8 2.2.2 Digitales Zertifikat . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.3 Zertifizierungsstellen . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Smartcard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.3.1 Arten von Chipkarten . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3.2 Kartenformate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.3.3 Smartcard-Mikrokontroller . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.4 Smartcard-Betriebssysteme . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.5 Dateien in der Smartcard . . . . . . . . . . . . . . . . . . . . . . . . 15 2.3.6 Datenübertragung zur Smartcard . . . . . . . . . . . . . . . . . . . . 17 2.3.7 Kommandos von Smartcards . . . . . . . . . . . . . . . . . . . . . . 19 2.3.8 Sicherheit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3 Selbstbediente Smartcard-Systeme 3.1 3.2 23 FlexiTrust Identity Management . . . . . . . . . . . . . . . . . . . . . . . . 23 3.1.1 Anwendungsszenarien . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.1.2 Software-Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.1.3 Smartcard-Prozesse . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 TUDCard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.2.1 Anwendungsszenarien . . . . . . . . . . . . . . . . . . . . . . . . . . 29 vii viii INHALTSVERZEICHNIS 3.2.2 Einrichtung der TUDCard . . . . . . . . . . . . . . . . . . . . . . . . 29 3.2.3 Smartcard-Prozesse . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4 Standardisierte Smartcard-Schnittstellen 33 4.1 PKCS#11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.2 PC/SC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 4.3 OCF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 4.4 CT-API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 5 Anforderungsanalyse 5.1 37 Smartcard-Servicefunktionen bestehender Systeme . . . . . . . . . . . . . . 37 5.1.1 Smartcard-Servicefunktionen von FlexiTrust Identity Management . 37 5.1.2 Smartcard-Servicefunktionen von TUDCard . . . . . . . . . . . . . . 38 5.2 Funktionale Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5.3 Qualitätsanforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 6 Design der Software 6.1 6.2 6.3 6.4 6.5 45 Verwaltung der Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 6.1.1 CardManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 6.1.2 ReaderDriver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 Kommunikation mit der Smartcard . . . . . . . . . . . . . . . . . . . . . . . 49 6.2.1 CardSlot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2.2 Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 CardServices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.3.1 CardService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.3.2 InfoCardService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.3.3 PasswordCardService 6.3.4 LoginCardService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.3.5 InitCardService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.3.6 DeleteCardService . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 6.3.7 SignatureCardService . . . . . . . . . . . . . . . . . . . . . . . . . . 61 6.3.8 CASignatureCardService . . . . . . . . . . . . . . . . . . . . . . . . . . 56 . . . . . . . . . . . . . . . . . . . . . . . . 62 Referenzierung der Daten auf der Smartcard . . . . . . . . . . . . . . . . . . 62 6.4.1 CardObjectID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 6.4.2 CardObjectRef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 APDU-Austausch mit der Smartcard . . . . . . . . . . . . . . . . . . . . . . 65 6.5.1 CommandApdu und ResponseApdu . . . . . . . . . . . . . . . . . . 65 6.5.2 ApduChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 6.5.3 ApduChannelCard . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 6.5.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 INHALTSVERZEICHNIS ix 6.6 Weitere Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 6.7 Konfiguration der Komponenten . . . . . . . . . . . . . . . . . . . . . . . . 70 7 Implementierungen 7.1 7.2 7.3 7.4 73 PKCS#11-Implementierung . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 7.1.1 PKCS11ReaderDriver, PKCS11CardSlot, PKCS11Card . . . . . . . 74 7.1.2 PKCS11CardServices 7.1.3 PKCS11CardObjectID . . . . . . . . . . . . . . . . . . . . . . . . . . 75 7.1.4 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 7.1.5 Anforderungen an die Umgebung . . . . . . . . . . . . . . . . . . . . 77 . . . . . . . . . . . . . . . . . . . . . . . . . . 74 Framework-Schnittstelle zu PC/SC . . . . . . . . . . . . . . . . . . . . . . . 77 7.2.1 PCSCReaderDriver und PCSCCardSlot . . . . . . . . . . . . . . . . 77 7.2.2 PCSCCardChannel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 7.2.3 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 7.2.4 Anforderungen an die Umgebung . . . . . . . . . . . . . . . . . . . . 78 Framework-Schnittstelle zu OCF . . . . . . . . . . . . . . . . . . . . . . . . 78 7.3.1 OCFReaderDriver und OCFCardSlot . . . . . . . . . . . . . . . . . 79 7.3.2 OCFPassThruCardChannel . . . . . . . . . . . . . . . . . . . . . . . 79 7.3.3 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 7.3.4 Anforderungen an die Umgebung . . . . . . . . . . . . . . . . . . . . 79 APDU-Level-Implementierung für TCOS2.0-Smartcard . . . . . . . . . . . . 80 7.4.1 TCOS20Card . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 7.4.2 TCOS20CardServices . . . . . . . . . . . . . . . . . . . . . . . . . . 81 7.4.3 TCOS20CardFileID . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 7.4.4 Secure-Messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 7.4.5 Weitere Klassen 7.4.6 Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 7.4.7 Anforderungen an die Umgebung . . . . . . . . . . . . . . . . . . . . 91 8 Ausblick 93 8.1 Weiterentwicklung der Software . . . . . . . . . . . . . . . . . . . . . . . . . 93 8.1.1 8.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Implementierung des Secure-Messaging für TCOS2.0 . . . . . . . . . 93 Anweisungen zur Software-Erweiterung . . . . . . . . . . . . . . . . . . . . . 94 8.2.1 Hinzunahme neuer CardServices . . . . . . . . . . . . . . . . . . . . 94 8.2.2 Hinzunahme neuer Kartenobjekte . . . . . . . . . . . . . . . . . . . 95 8.2.3 Implementierung für andere Smartcards und Kartenschnittstellen . . 95 9 Zusammenfassung 97 Literaturverzeichnis 101 x INHALTSVERZEICHNIS Kapitel 1 Einleitung 1.1 Motivation Eine Public-Key-Infrastruktur (PKI) sorgt für eine sichere Kommunikation in offenen (und damit unsicheren) elektronischen Kommunikationsnetzen, insbesondere dem Internet, indem sie ihren Mitgliedern folgendes bietet: • Authentifikation und Autorisierung • Vertrauliche Kommunikation • digitale Unterzeichnung elektronischer Dokumente Dabei kommen kryptographische Verfahren zur Verwendung, deren Einsatz weitgehend vom Endanwender verborgen wird. Die Sicherheit einer PKI beruht auf der Sicherheit der sensiblen Daten der Infrastruktur - der privaten Schlüssel der Teilnehmer, welche in der sogenannten persönlichen Sicherheitsumgebung (personal security enviroment, PSE ) aufbewahrt werden. Dabei handelt es sich um einen speziell geschützten Computerbereich den die privaten Schlüssel per Definition nie verlassen. Smartcards stellen eine hochsichere PSE dar, denn sie bieten eine physikalische Abschottung der Geheimnisse. Geheime Schlüssel können dort sicher gespeichert werden. Die Chipkarten können ebenfalls genutzt werden, um innerhalb der Karte Informationen zu ver- und entschlüsseln sowie um digitale Signaturen zu erstellen und zu überprüfen. Über die kryptographischen Funktionen hinaus können Chipkarten zusätzliche Informationen und Applikationen speichern. Beim klassischen Smartcard-Rollout in Rahmen einer PKI werden Smartcards zentral produziert und dann ein einem sehr zeit- und aufwandintensiven Prozess verteilt. Für viele Anwendungen ist dieses Verfahren nicht akzeptabel, weil es die reibungslose Abwicklung von Geschäftsprozessen empfindlich stört: 1 2 KAPITEL 1. EINLEITUNG • Ein Mitarbeiter, der bei seinen Aufgaben auf EDV-Systeme angewiesen ist und seine Smartcard vergisst oder verlegt kann nicht arbeiten, bis er eine neue Smartcard erhält. • Vertretungsfunktionen lassen sich nur sehr aufwendig organisieren. • Schnelle Verfügbarkeit und Schutz von Daten lassen sich schlecht miteinander vereinbaren. Es werden neue Verfahren gesucht, welche die Datenverfügbarkeit erhöhen ohne dabei das Sicherheitsniveau zu reduzieren. Eine Lösungsvariante besteht darin, die SmartcardProzesse dezentral und ggf. selbstbedient zu realisieren. Damit lässt sich eine flexible Smartcard-Rollout-Infrastuktur aufbauen, die den eigenen Bedürfnissen und Anforderungen genau entspricht. Dabei erlauben Smartcard-Servicefunktionen eine einfache und Ressourcen schonende Integration von Smartcard-Sicherheitsanwendungen in die bestehende Geschäftsprozesse. Unter anderem sind darunter insbesondere folgende Prozesse zu verstehen: • Personalisierung und Verteilung von Smartcards • Erneuern von Smartcards • Wiederherstellen von Teilen der Smartcard-Inhalte • Ermitteln des Smartcard-Status • Löschen von Smartcards • Entsperren von Smartcards 1.2 Aufgabenstellung Das Ziel der Diplomarbeit ist Entwurf und prototypische Implementierung einer SoftwareLösung, welche die im Abschnitt 1.1 charakterisierten Probleme löst, d.h. eine flexible Smartcard-Anbindung an Sicherheitsanwendungen ermöglicht und dezentrale SmartcardProzesse durch Smartcard-Servicefunktionen unterstützt. Sie soll insbesondere folgende Eigenschaften aufweisen: • Flexibilität – Die Software soll die Möglichkeit mit sich bringen, verschiedene Smartcards und Smartcard-Schnittstellen zu verwenden. – Die Implementierung sollte für den Anwender weitestgehend transparent und jederzeit austauschbar sein. 1.3. AUFBAU DER ARBEIT 3 • Erweiterbarkeit – Die Software soll so konzipiert sein, dass sie Erweiterungen möglichst einfach zulässt, wenn zum Beispiel neue Smartcards oder Smartcard-Schnittstellen erscheinen. – Neue Funktionalität soll einfach hinzugefügt werden können. Im Rahmen dieser Arbeit sollen die bestehenden selbstbedienten Smartcard-Systeme analysiert werden und so genaue Anforderungen an eine flexible Smartcard-Anbindung in Sicherheitsinfrastrukturen ermittelt werden. Anschließend sollen die technischen Umsetzungsmöglichkeiten dieser Anforderungen einer Analyse unterzogen werden, wobei die standardisierte Smartcard-Schnittstellen eine wichtige Rolle spielen. Die zu entwickelnde Software soll Smartcard-Servicefunktionen realisieren indem sie geeignete Abstraktionen für verfügbare Funktionen seitens der Hard- und Software (Smartcard-Betriebssystemen und standardisierten Smartcard-Schnittstellen) anbietet. 1.3 Aufbau der Arbeit Die vorliegende Ausarbeitung ist wie folgt aufgebaut: Im Kapitel 2, Grundlagen, wird zunächst Public-Key-Kryptographie und Public-KeyInfrastrukturen erklärt und eine Einführung in die Technologie von Chipkarten gegeben. Dies ist notwendig, denn zum Verständnis der vorliegenden Arbeit wird lediglich Grundwissen im Bereich der Informatik vorausgesetzt. Das Kapitel 3, Selbstbediente Smartcard-Systeme, widmet sich dem Umfeld, in dem die Software entstanden ist. Es werden zwei selbstbediente Smartcard-Systeme vorgestellt, FlexiTrust Identity Management und TUDCard. Im Kapitel 4, Standardisierte Smartcard-Schnittstellen, werden die gängigen standardisierten Smartcard-Schnittstellen analysiert und untereinander verglichen. Die genauen Anforderungen an die zu entwickelnde Software werden im Kapitel 5, Anforderungsanalyse, ermittelt. Das Kapitel 6, Design der Software, beschreibt das Design des entworfenen Frameworks. Im Kapitel 7, Implementierungen, wird auf die Implementierungen des Frameworks für die TCOS2.0-Smartcard mit Kartenschnittstellen PKCS#11, PC/SC und OCF eingegangen. Anweisungen zur Weiterentwicklung und Erweiterung des Frameworks werden im Kapitel 8, Ausblick, gegeben. Das Kapitel 9, Zusammenfassung, möchte am Schluss diese Arbeit zusammenfassen. In dieser Ausarbeitung werden wichtige Aspekte oder Bezeichner kursiv hervorgehoben, Literaturverweise werden in eckigen Klammern [...]“ aufgeführt. Am Ende dieser ” 4 Ausarbeitung ist das Literaturverzeichnis zu finden. KAPITEL 1. EINLEITUNG Kapitel 2 Grundlagen In diesem Kapitel wird das für das Verständnis dieser Ausarbeitung notwendige Grundwissen in Public-Key-Kryptographie, Public-Key-Infrastrukturen und in der Technologie der Chipkarten vorgestellt. Auf eine tiefere Einführung, insbesondere auf mathematische Grundlagen und auf Algorithmen wurde bewusst verzichtet, da die vorliegende Diplomarbeit eine praktische Anwendung behandelt. 2.1 Public-Key-Kryptographie Kryptographie wurde lange Zeit als die Lehre von der Datenverschlüsselung bezeichnet, die es ermöglicht hat, vertrauliche Nachrichten sicher auszutauschen. Moderne kryptographische Techniken dienen nicht nur der Vertraulichkeit, sondern auch weiteren Schutzzielen: Authentizität, Integrität und Zurechenbarkeit. Die Schutzziele werden wie folgt definiert [Johge]: Vertraulichkeit garantiert, dass nur Berechtigte Zugang zu Informationen haben. Sie wird mit Hilfe von Verschlüsselungsverfahren gewährleistet. Unter Authentizität wird die Echtheit und Glaubwürdigkeit elektronischer Nachrichten verstanden. Kryptographische Techniken geben Aufschluss über die Identität des Absenders und garantieren damit die Authentizität der Nachricht. Integrität der Daten wird gewährleistet, wenn es unmöglich ist, sie unbemerkt zu manipulieren. Mit kryptographischen Methoden kann überprüft werden, ob die Daten verändert wurden. Zurechenbarkeit elektronischer Dokumente bedeutet, dass es einem Dritten gegenüber nachgewiesen werden kann, dass ein Dokument von einem bestimmten Absender kommt. Dafür verwendet man digitale Signaturen. 5 6 KAPITEL 2. GRUNDLAGEN 2.1.1 Public-Key-Verschlüsselung Bei den symmetrischen Verschlüsselungsverfahren, dem klassischen Gegenstand der Kryptographie, müssen der Absender und der Empfänger der Nachricht den gleichen symmetrischen Schlüssel besitzen, der geheim gehalten werden muss. Daher wird die Verteilung und die Verwaltung der Schlüssel zu einem zentralen Problem. Jedes Mal, wenn Alice und Bob miteinander vertraulich kommunizieren wollen, müssen sie vorher einen geheimen Schlüssel austauschen. Mit der steigenden Anzahl der Teilnehmer in den heutigen Netzen werden symmetrische Verfahren unpraktikabel. Das Schlüsselmanagement wird einfacher, wenn man Public-Key-Verfahren (auch als asymmetrische Verfahren bezeichnet) einsetzt. In diesem Fall besitzt jeder Teilnehmer ein Schlüsselpaar, welches aus einem öffentlichen und aus einem privaten Schlüssel besteht. Der private Schlüssel ist dem Inhaber allein bekannt und muss an einem sicheren Ort aufbewahrt werden. Der öffentliche Schlüssel darf dagegen jedem Kommunikationsteilnehmer mitgeteilt werden. Will Alice eine Nachricht an Bob schicken, so soll sie zuerst sicher stellen, dass sie im Besitz von Bobs öffentlichen Schlüssel ist. Sie verschlüsselt die Nachricht mit diesem Schlüssel und schickt sie an Bob. Bob kann die Nachricht mit seinem privaten Schlüssel entschlüsseln. Durch Public-Key-Verfahren werden Probleme der symmetrischen Kryptographie gelöst: Es müssen keine geheimen Schlüssel ausgetauscht werden und Bob braucht nur ein Schlüsselpaar, um mit allen Teilnehmern zu kommunizieren. Das ist ein großer Vorteil. Es gibt aber ein anderes Problem. Wer eine Nachricht an Bob schicken will, muss sicher sein, dass der öffentliche Schlüssel tatsächlich der öffentliche Schlüssel von Bob ist. Wenn es einem Angreifer gelingt, den öffentlichen Schlüssel von Bob mit seinem eigenen zu ersetzen, so kann er die Nachrichten, die für Bob bestimmt sind, lesen. Es ist also notwendig, eine zweifelsfreie Zuordnung einer Identität zu einem öffentlichen Schlüssel zu garantieren. Wie dies gewährleistet werden kann, wird im Abschnitt 2.2 beschrieben. Das wichtigste Public-Key-Verfahren ist heute das RSA-Verfahren, das überall zum Einsatz kommt. Seine Sicherheit beruht auf dem Faktorisierungsproblem. Da die bekannten Public-Key-Verfahren nicht so effizient sind wie die symmetrischen Verfahren, werden in der Praxis häufig die sogennanten Hybrid-Verfahren benutzt. Will Alice eine Nachricht an Bob schicken, verschlüsselt sie mit dem öffentlichen Schlüssel von Bob nur einen symmetrischen Sitzungsschlüssel, den sie dann zur Verschlüsselung der Nachricht benutzt und in verschlüsselter Form dem Schlüsseltext anhängt. Bob wird zuerst mit seinem privaten Schlüssel den Sitzungsschlüssel entschlüsseln, womit er dann die Nachricht entschlüsseln kann. 2.2. PUBLIC-KEY-INFRASTRUKTUR 2.1.2 7 Digitale Signaturen Um die Authentizität und Zurechenbarkeit elektronischer Dokumente zu garantieren, verwendet man digitale Signaturen. Diese haben eine ähnliche Funktion wie gewöhnliche Unterschriften. Wird ein Dokument von Bob digital signiert, so kann es nachgewiesen werden, dass das Dokument tatsächlich von Bob kommt. Außerdem kann Bob später nicht abstreiten, das Dokument signiert zu haben. Aus jedem deterministischen Public-Key-Verschlüsselungsverfahren, dessen Ver- und Entschlüsselung vertauschbar sind, lässt sich ein Signaturverfahren konstruieren. Will Bob eine Nachricht digital signieren, so entschlüsselt er sie mit seinem privaten Schlüssel. Damit erhält er die Signatur der Nachricht. Bob schickt die Nachricht und die Signatur an Alice. Sie kann dann die Signatur mit dem öffentlichen Schlüssel von Bob verifizieren. Dafür verschlüsselt Alice damit die Signatur und überprüft, ob der erhaltene Wert mit der Nachricht übereinstimmt. Dieses Verfahren hat aber einen Schwachpunkt. Wenn es einem Angreifer gelingt, Alice seinen öffentlichen Schlüssel als den von Bob zu unterschieben, so wird Alice seine Signaturen als die von Bob verifizieren. Auch hier kommen Public-Key-Infrastrukturen zum Einsatz, um eine zweifelsfreie Zuordnung einer Identität zu einem öffentlichen Schlüssel zu garantieren. 2.2 Public-Key-Infrastruktur Public-Key-Verfahren allein können nicht dafür sorgen, dass die Schutzziele (s. Abschnitt 2.1) erfüllt werden. Es muss gewährleistet werden, dass die privaten Schlüssel geheim bleiben und die öffentlichen Schlüssel vor Fälschung und Mißbrauch geschützt werden. Hier kommt die Public-Key-Infrastruktur (PKI) ins Spiel. Eine Public-Key-Infrastruktur ist ein System zur Bereitstellung der Sicherheit der praktischen Nutzung asymmetrischer Kryptoverfahren. Eine PKI agiert als ein Dritter, der die folgenden Aufgaben vertrauenswürdig erledigt: • Erzeugung und Speicherung von Schlüsselpaaren • Schutz der privaten Schlüssel • Zweifelsfreie Zuordnung einer Identität zu einem öffentlichen Schlüssel • Verteilung der öffentlichen Schlüssel • Außerbetriebnahme und Vernichtung von Schlüsselpaaren • ggf. Archivierung und Wiederherstellung von Schlüsselpaaren Im folgenden werden einige Organisationsprinzipien von Public-Key-Infrastrukturen erläutert. 8 KAPITEL 2. GRUNDLAGEN 2.2.1 Persönliche Sicherheitsumgebung Um die Schutzziele Vertraulichkeit, Authentizität und Zurechenbarkeit zu erfüllen, muss Bobs privater Schlüssel geheim bleiben. Sonst kann nämlich jeder, der ihn kennt, verschlüsselte Nachrichten an Bob lesen und Bobs Signatur fälschen. Daher werden die privaten Schlüssel in einer speziell geschützten Umgebung aufbewahrt, welche als persönliche Sicherheitsumgebung (personal security enviroment, PSE ) bezeichnet wird. Eine PSE garantiert sichere Speicherung privater Schlüssel. Der Zugang zu einer persönlichen Sicherheitsumgebung muss geschützt werden, er darf erst nach einer Authentifikation stattfinden. Dazu gibt es drei (kombinierbare) Möglichkeiten : • Authentifikation durch Wissen Die PSE darf erst nach Eingabe eines nur dem Besitzer und der PSE bekannten Passwortes benutzt werden. • Authentifikation durch Besitz Die PSE ist nur dem Besitzer zugänglich. • Authentifikation durch persönliches Merkmal Biometrische Merkmale wie der Fingerabdruck werden zur Authentifizierung herangezogen. Software-PSE Bei einer einfachen Software-PSE (auch Softtoken genannt) geschieht die Erzeugung und die Verwendung der privaten Schlüssel in der Regel innerhalb eines vom Betriebssystem speziell geschützten Speicherbereichs. In diesem Fall ist man sehr auf die Sicherheitsmechanismen des Betriebssystems angewiesen. Es ist bekannt, dass man mit entsprechendem Aufwand Schutzfunktionen des Betriebssystems umgehen kann. Die Speicherung und der Transport der privaten Schlüssel findet gewöhnlich innerhalb einer nach PKCS#12 [RSAc] mit einem Passwort symmetrisch verschlüsselten Datei statt. Der Passwortschutz ist allgemein nicht besonders sicher. Zum Beispiel können Passwörter durch Trojaner ausgespäht werden [Joh]. Außerdem braucht der Angreifer keinen permanenten Zugang zum Rechner des Softtoken-Inhabers, um das Passwort zu ermitteln — die Datei kann einfach auf eine andere Maschine kopiert werden, um dort in aller Ruhe das Passwort zu brechen (zum Beispiel durch Brute Force Attack ) [Cha99]. Andererseits bringen die Softtoken im Vergleich zu Hardware-PSEs eine bedeutende Kostenersparnis mit sich. Sie können auf jedem PC ohne zusätzliche Hardware (Kartenleser und Chipkarten) benutzt werden. 2.2. PUBLIC-KEY-INFRASTRUKTUR 9 Hardware-PSE Für sicherheitskritische Anwendungen reicht der Schutz einer Software-PSE nicht aus. Sicherer ist es, die persönliche Sicherheitsumgebung in einen externen Hardware-Modul (auch Hardtoken genannt) auszulagern. Dabei handelt es sich um kleine Computer mit einem Kryptoprozessor, die auf bestimmte kryptographische Aufgaben ausgerichtet sind. Diese Geräte sind typischerweise in der Lage, Schlüsselpaare intern zu generieren, oder können mit einem Schlüsselpaar von außen initialisiert werden. Die Hardtoken können symmetrische und asymmetrische kryptographische Operationen ausführen. Der private Schlüssel verlässt nie die Hardware-PSE, in der er physikalisch geschützt ist, kann nicht ausgelesen oder kopiert werden. Das ist der wichtigste Vorteil von Hardtoken. Ein anderer Vorteil ist, dass der Benutzer sein Hardtoken immer bei sich haben kann. Somit ist es von jedem Computer aus verwendbar und besser als Softtoken von unberechtigtem Zugang geschützt. Die Benutzung von Hardtoken setzt im Gegensatz zu Softtoken eine Zwei-Faktor-Authentifikation voraus — durch den Besitz des Tokens und das Wissen des entsprechenden PIN-Codes. Da die Rechenleistung Hardware-Module meist sehr begrenzt ist, lassen sich große Datenmengen nicht in vertretbarer Zeit ver- oder entschlüsseln. Daher verwendet man Hybrid-Verfahren (s. Abschnitt 2.1.1), wobei nur der Sitzungsschlüssel im Hardware-Modul entschlüsselt wird. Die Entschlüsselung der Nachricht erfolgt dann im PC, mit dem das Hardtoken verbunden ist. Hardtoken werden meistens als Chipkarten(s. Abschnitt 2.3) oder als Hardware Security Modules [hsm] realisiert. Der Nachteil dieser Lösung im Vergleich zu Software-PSE ist eine erhebliche Kostenerhöhung der PKI. 2.2.2 Digitales Zertifikat Für die Sicherheit der praktischen Nutzung von Public-Key-Verfahren ist notwendig, eine zweifelsfreie Zuordnung einer Identität zu einem öffentlichen Schlüssel zu garantieren. Um den Einsatz falscher (zum Beispiel untergeschobener) Schlüssel zu verhindern, wird ein Nachweis benötigt, dass der verwendete öffentliche Schlüssel tatsächlich dem designierten Empfänger der verschlüsselten Nachricht bzw. dem Sender einer digital signierten Nachricht gehört. Diesen Nachweis stellt eine vertrauenswürdiger Dritter (eine Zertifizierungsstelle) in Form eines digitalen Zertifikates aus. Ein digitales Zertifikat enthält mindestens folgende Informationen [pki]: • den Namen des Inhabers, • dessen öffentlichen Schlüssel, • die Bezeichnung des Algorithmus , mit denen der öffentliche Schlüssel benutzt werden kann, 10 KAPITEL 2. GRUNDLAGEN • eine Seriennummer, • eine Gültigkeitsdauer, • den Namen der Zertifizierungsstelle, • Angaben ob die Nutzung der Schlüssel auf bestimmte Anwendungen beschränkt ist. Diese Daten sind mit dem privaten Schlüssel des Ausstellers digital signiert und können somit mit dem öffentlichen Schlüssel des Ausstellers überprüft werden. Das Zertifikat wird zusammen mit dem Namen des Benutzers in einem Verzeichnis veröffentlicht. Alle PKI-Teilnehmer können das Verzeichnis lesen. Zertifikate für Schlüssel, die nicht mehr sicher sind, können über eine so genannte Zertifikatsperrliste gesperrt werden. Der wichtigste Standard für digitale Zertifikate ist derzeit der ITU-T-Standard für eine Public-Key-Infrastruktur X.509. Die aktuelle Version X.509v3 ist im Standard [rfc] beschrieben. 2.2.3 Zertifizierungsstellen Die Rolle des vertrauenswürdigen Dritten, der u.a. digitale Zertifikate ausstellt, übernimmt in Rahmen einer PKI eine sogennante Zertifizierungsstelle. Da diese zentrale Komponente unter Kontrolle des PKI-Betreibers steht und durch zahlreiche Schutzmaßnahmen abgesichert ist, wird sie auch Trustcenter genannt. Die Aufgaben einer Zertifizierungsstelle verlangen einen hohen Grad an Sicherheit und umfassen sehr komplizierte und umfangreiche Prozesse. Um dies zu ermöglichen, wird eine Zertifizierungsstelle in der Praxis oft in mehrere Komponenten aufgeteilt, deren Aufgaben kurz beschrieben werden. Registrierungsinstanz Die Registrierungsinstanz (Registration Authority, RA) übernimmt die Registrierung neuer Benutzer der PKI. Ein neuer Benutzer beantragt bei der Registrierungsinstanz ein Zertifikat und teilt gleichzeitig seinen Namen und andere erforderliche Daten (persönliche Daten, Kontaktinformationen, Abrechnungsdaten etc.) mit. Die Registrierungsinstanz überprüft die Benutzerdaten, wozu es verschiedene Möglichkeiten gibt. Die Überprüfung der Daten kann zum Beispiel per Email oder durch persönliches Erscheinen des Antragstellers erfolgen. Nach einer erfolgreichen Datenüberprüfung wird ein innerhalb der PKI eindeutiger digitaler Benutzername erzeugt. Alle für die Ausstellung des Zertifikats notwendigen Daten werden von der Registrierungsinstanz signiert und meist in Form eines PKCS#10-Antrags [RSAa] an die Zertifizierungsinstanz übermittelt. Bei der Registrierungsinstanz können die Nutzer ihre Zertifikate auch verlängern und oft auch Passwörter zur Sperrung des privaten Schlüssels erhalten. 2.3. SMARTCARD 11 Zertifizierungsinstanz Die Hauptaufgabe der Zertifizierungsinstanz (Certification Authority, CA) ist die Ausstellung von Zertifikaten. Die Zertifizierungsinstanz erstellt ein Zertifikat, indem sie den String aus allen im Zertifikat enthaltenen Informationen mit ihrem privaten Schlüssel signiert. Falls die Schlüsselpaare für die Endnutzer zentral erzeugt werden, geschieht dies vor der Ausstellung des Zertifikats auch in dieser Instanz, sowohl für Soft- als auch für Hardtoken. Es wird auch ein Transportpasswort erzeugt, um einen sicheren Transport zum Eigentümer zu garantieren. Manchmal muss ein Zertifikat als ungültig erklärt werden, obwohl seine Gültigkeitsdauer noch nicht abgelaufen ist, zum Beispiel weil der private Schlüssel kompromittiert wurde. In dem Fall ist es eine Aufgabe der Zertifizierungsinstanz, das ungültige Zertifikat in eine Zertifikatsperrliste, auch Revokationsliste (certificate revocation list, CRL) genannt, einzutragen. Die Zertifikatsperrlisten werden auch signiert. Die vorzeitige Sperrung von Zertifikaten wird als Revokation bezeichnet. Diese Komponente des Trustcenters ist am sicherheitskritischsten, denn falls ihr privater Schlüssel kompromittiert wird, kann man den Zertifikaten aller Teilnehmer nicht mehr vertrauen. Deswegen wird die Zertifizierungsinstanz von dem PKI-Betreiber technisch und organisatorisch besonders geschützt, zum Beispiel durch Offline-Betrieb und physikalische Abschirmung. Verzeichnisdienst Der Verzeichnisdienst (Certificate Management Authority, CMA) gewährleistet die Verfügbarkeit der von der Zertifizierungsinstanz erstellten Produkte. Zertifikate und Revokationslisten werden von dieser Instanz in einem Verzeichnis (Directory) veröffentlicht. Alle Teilnehmer der PKI können auf das Verzeichnis zugreifen, um die aktuellen Informationen über sie interessierende Zertifikate abzurufen. Das dafür gängigste Protokoll ist LDAP (Lightweight Directory Access Protocol ). Falls die Schlüsselpaare zentral erzeugt werden, übernimmt der Verzeichnisdienst auch die Auslieferung von Soft- und Hardtoken an ihre Eigentümer. Dies kann per Post (Hardtoken), durch persönliche Übergabe oder per Email (Softtoken) geschehen. 2.3 Smartcard Als Geburtsstunde der Chipkarte gilt das Jahr 1974, in dem dem Franzosen R. Moreno ein Patent für ein System zur Speicherung von Daten in einem unabhängigen, tragbaren ” Gegenstand“ erteilt wurde ([Clage], S. 465). Die heutige Chipkarte ist eine Plastikkarte, in deren Kartenkörper eine integrierte Schaltung, ein Chip, eingebaut ist. Der Chip verfügt über Elemente zur Speicherung, Verarbeitung und Übertragung von Daten. Der wichtigste 12 KAPITEL 2. GRUNDLAGEN Vorteil der Chipkarte liegt darin, dass die in ihr gespeicherten Daten gegen unberechtigten Zugriff und Manipulation sehr gut geschützt sind. Einen sehr guten Überblick über die Architektur, Betriebssoftware und Anwendungsgebiete von Chipkarten gibt das Buch von Rankl und Effing [Wolge]. Der Standard ISO/IEC 7816 enthält enthält Vorgaben für physikalische und elektrische Eigenschaften, sowie für die Übertragungsprotokolle. In dem Standard werden die Chipkarten als Integrated Circuit Card (ICC) bezeichnet. 2.3.1 Arten von Chipkarten Chipkarten kommen in unterschiedlichen Ausprägungen vor. Die einfachsten Varianten sind reine Speicherkarten, die nur über einen Speicher, meist ein EEPROM, verfügen. Speicherkarten besitzen keine CPU, sind also nicht rechenfähig. Der Zugriff auf den Speicher wird durch die Sicherheitslogik kontrolliert, welche im einfachsten Fall nur aus einem Schreib- oder Löschschutz besteht. Es gibt aber auch Speicherchips mit komplexerer Sicherheitslogik, welche eine Überprüfung der PIN oder einfache Verschlüsselung durchführen können. Die Funktionalität von Speicherkarten ist meist auf eine spezielle Anwendung beschränkt. Dafür können derartige Karten sehr preiswert produziert werden. Typische Anwendungen für Speicherkarten sind vorbezahlte Telefonkarten oder Krankenversichertenkarten. Ist der Kartenchip mit einem Mikroprozessor ausgestattet, so spricht man von einer Mikroprozessorkarte oder einer Smartcard. Smartcards sind in ihrer Anwendung sehr flexibel und in vielfältigen Bereichen einsetzbar. Beispiele für Mikroprozessorkarten sind die JavaCard oder die Geldkarte. Ausgestattet mit einem Krypto-Coprozessor ermöglichen Smartcards die Realisierung eines handlichen Sicherheitsmoduls, welches jederzeit, zum Beispiel in dem Geldbeutel, mitgenommen werden kann. In Rahmen einer PKI können Smartcards als Hardware-PSE verwendet werden. Man unterscheidet zwischen kontaktbehafteten und kontaktlosen Chipkarten. Kontaktbehaftete Chipkarten interagieren mit ihrer Umwelt über acht Kontakte, wie es in der Norm ISO/IEC 7816-1 definiert ist. Dafür muss die Karte in einen Kartenleser eingeführt werden. Die direkte Verbindung der Oberfläche der Chipkarte mit den Eingängen der integrierten Schaltung im Kartenleser ist aber eine häufige Quelle elektromechanischer Fehler. Kontaktlose Chipkarten lösen dieses Problem und eröffnen neue Möglichkeiten. Die Verbindung zu einer solchen Karte wird über eine Antenne aufgebaut, die im Kartenkörper plaziert ist. Kontaktlose Karten bringen große Vorteile, wenn die Benutzung schnell und bei großen Menschenmengen durchgeführt werden muss, zum Beispiel in Systemen bargeldloser Zahlungen oder in Zugangskontrollsystemen, wo die Nutzer bezahlen oder sich authentifizieren ohne die Karte in einen Kartenleser einzustecken. Eine zusätzliche Kategorie bilden Hybridkarten, die mit zwei unterschiedlichen Kartentechnologien arbeiten. Zum Beispiel verfügen solche Karten sowohl über einen kontaktbehafteten als auch über 2.3. SMARTCARD 13 einen kontaktlosen Chip. 2.3.2 Kartenformate Es wurden schon lange Chipkarten in der Kreditkartengröße verwendet. Dieses Format ist das bekannteste und hat die Bezeichnung ID-1. Die Abbildung 2.1 präsentiert eine Chipkarte in diesem Format. Es handelt sich um eine Karte mit abgerundeten Ecken, die 85,6 mm lang, 54 mm breit und 0,76 mm dick ist. Es hat den Vorteil, sehr gut handhabbar zu sein. Die Karte lässt sich in Taschen oder Geldbeutel stecken und ist nicht so klein, dass sie leicht verloren werden kann. Sie ist nicht so steif, dass sie leicht gebrochen werden kann. Bankkarten und Krankenversichertenkarten sind weitere Beispiele von Karten im ID-1 Format. Abbildung 2.1: TUDCard, eine Chipkarte im ID-1 Format [tudb]. Allerdings erfüllt das Format ID-1 die Anforderungen von heute immer üblichen kleinen Geräten nicht mehr. Ursprünglich für Mobiltelefone entwickelte ID-000 Format definiert eine Plug-In Karte in Briefmarkengröße, und kommt am häufigsten in Mobilfunkgeräten zum Einsatz. Die Karte ist 25 mm lang, 15 mm breit und 0,76 mm dick. Drei Ecken der Karte sind abgerundet, die rechte untere Ecke ist im Winkel von 45◦ abgetrennt, um eine eindeutige Orientierung beim einlegen der Karte sicherzustellen. Da die manuelle Handhabung solcher Karten nicht gerade einfach ist, wird die SIM-Karte im Mobilfunkbereich ihrem Eigentümer üblicherweise als eine ID-1 Karte übergeben, die so vorgestanzt ist, dass man durch Ausbrechen eine ID-000 Karte erhält. Es gibt noch ein Format, welches als ID-00 oder Minikarte bezeichnet wird. Minikarten haben abgerundete Ecken, sind 66 mm lang, 33 mm breit und 0,76 mm dick. Eine ID-00 Karte verzichtet im Vergleich zum Format ID-1 lediglich auf überflüssiges Plastik und kann aus einer ID-1 Karte durch Ausstanzen hergestellt werden. Ihre Kontakte sind auf die gleiche Art angeordnet, deshalb können Kartenlesegeräte beide Kartentypen akzeptieren. 14 KAPITEL 2. GRUNDLAGEN 2.3.3 Smartcard-Mikrokontroller Der zentrale Baustein einer Smartcard ist der unter den Kontaktflächen eingebettete Mikrokontroller. Seine Architektur ist der Architektur eines PC sehr ähnlich. Der Mikrokontroller ist mit einem Prozessor, drei verschiedenen Speicherarten (RAM, ROM und EEPROM) und einer seriellen Ein-/Ausgabeschnittstelle ausgestattet. Zusätzlich kann der Mikrokontroller spezielle Rechenwerke enthalten, die als mathematische Koprozessoren fungieren und zur beschleunigten Ausführung modularer Arithmetik oder zur Beschleunigung von Exponentationen eingesetzt werden. Die Funktionseinheiten sind über einen Adress- und Datenbus mit dem Prozessor verbunden. Neben der CPU sind die verschiedenen Speicher die wichtigsten Bausteine eines Smartcard-Mikrokontrollers. Die typische Aufteilung umfasst drei Speicherbereiche: ROM (Read Only Memory) ist maskenprogrammiert und über seine Lebensdauer unveränderbar. Er enthält das Betriebs RAM (Random Access Memory) ist ein flüchtiger Speicher, dessen Inhalt verloren geht, sobald die Stromversorgung nicht mehr vorhanden ist. Er dient dem Prozessor als Arbeitsspeicher, in dem Daten während einer Sitzung gespeichert und geändert werden können. Die Anzahl der möglichen Zugriffe ist unbegrenzt und sie sind sehr schnell. Da der RAM einen großen Flächenbedarf hat, ist er im Vergleich zu anderen Speicherbausteinen klein, seine Größe variiert von einigen Hundert Byte bis zu 16 KByte. EEPROM (Electronically Erasable Programmable ROM ) ist ein nicht flüchtiger Speicher, dessen Daten bei Bedarf gelöscht oder verändert werden können. Es sind mindestens 100.000 Umprogrammierungen mittels elektrischer Signale möglich. Die Funktionalität des EEPROM-Speichers entspricht der Festplatte eines PC, weil Daten auch ohne Stromversorgung erhalten bleiben und geändert werden können. Dieser Speicher wird zur langfristigen Speicherung von veränderbaren benutzerspezifischen Daten benutzt, wie zum Beispiel die PIN oder die kryptographischen Schlüssel. Seine Größe reicht von 8 bis 400 KByte. 2.3.4 Smartcard-Betriebssysteme Genau so wie ein PC, braucht ein Smartcard-Mikrokontroller ein Betriebssystem, das die Steuerung und Kontrolle von Programmen übernimmt. Im Gegensatz zu üblichen Betriebssystemen besitzen die Smartcard-Betriebssysteme keine Benutzeroberfläche und sind nicht auf die Kontrolle externer Hardware hin optimiert. Viel mehr stehen die Sicherheitsfunktionen im Vordergrund. Ein Smartcard-Betriebssystem hat die folgenden Hauptaufgaben: • Datenaustauch mit der Chipkarte 2.3. SMARTCARD 15 • Dateiverwaltung • Ablaufsteuerung der Kommandos • Verwaltung und Ausführung von Programmcode • Kryptographische Funktionen • Zugriffskontrolle und Sicherheit Für die Smartcard-Betriebssysteme hat sich die Bezeichnung COS (Card Operating System) eingebürgert. Viele Hersteller stellen ihre Produktbezeichnung voran, wodurch sich eigene Produktnamen ergeben. Die gängigen Betriebssysteme für Chipkarten sind TCOS von Telesec, STARCOS von Giesecke & Devrient, CardOS von Siemens, etc. Das Betriebssystem wird vom Hersteller als ROM der Chipkarte eingebaut. Aufgrund der Einschränkungen durch den zur Verfügung stehenden Speicherplatz haben die Smartcard-Betriebssysteme einen sehr kleinen Code-Umfang, im Durchschnitt bis zu 64 KByte. Da sie als ROM-Code geschrieben werden, können nach der Herstellung des ROMs keine Änderungen vorgenommen werden. Dies führt dazu, dass auf viele für andere Betriebssysteme übliche Abläufe, wie Updates und selbstmodifizierenden Code, verzichtet werden muss. Außerdem ist nach der Herstellung des ROMs eine Fehlerbeseitigung nicht mehr möglich, deswegen müssen diese Betriebssysteme extrem zuverlässig und robust sein. 2.3.5 Dateien in der Smartcard Der Aufbau von Smartcard-Dateisystemen ist in der Norm ISO/IEC 7816-4 festgelegt. Smartcards verfügen über ein hierarchisch organisiertes Dateiverwaltungssystem mit symbolischer und Hardware-unabhängiger Adressierung. Die Dateien werden mit hexadezimalen Codes adressiert. Alle Dateien besitzen einen zwei Byte langen File Identifier (FID), unter dessen Verwendung sie selektiert werden können. Wenn auf eine Datei zugegriffen werden muss, ist es die Aufgabe der Dateiverwaltung, die logischen Adressen in physikalischen Adressen des Chips umzusetzen. Die Dateiverwaltungssysteme für Smartcards sind objektorientiert aufgebaut [Wolge]. Das bedeutet, dass Informationen über eine Datei in dieser Datei selbst gespeichert sind. Der Dateiheader, auch Dateideskriptor genannt, enthält alle Informationen über die Struktur und den Aufbau der Datei, während im Dateibody die Nutzdaten gespeichert sind. Vor einem Zugriff muss die Datei immer zuerst selektiert werden. Es existieren zwei Dateitypen, Verzeichnisse, Dedicated Files (DFs) genannt, und Elementary Files (EFs). Verzeichnisse fungieren als Kontainer für weitere Dateien (DFs oder EFs) und EFs enthalten die eigentlichen Nutzdaten. Nach Konvention werden alle EFs, die zu einer Anwendung gehören, in einem DF gespeichert. Das Wurzelverzeichnis wird als Master File (MF) bezeichnet. Dafür ist der File Identifier 3F00 reserviert. 16 KAPITEL 2. GRUNDLAGEN Im Gegensatz zu Dateien in üblichen Betriebssystemen können EFs unterschiedliche interne Struktur aufweisen. Dies hat zum Zweck, Dateizugriffe zu optimieren. Die wichtigsten Dateistrukturen sind: • Transparent Eine transparente Dateistruktur stellt eine lineare Anordnung von Bytes, ein ByteArray, dar. Auf die Daten kann blockweise mit einem Offset schreibend und lesend zugegriffen werden. In den EFs mit transparenter Struktur werden nicht strukturierte oder sehr kurze Daten gespeichert, wie zum Beispiel ein digitales Passfoto oder die PIN. • Linear fixed Die linear fixed Dateistruktur ist eine Aneinanderreihung von gleich langen Datensätzen, den sogenannten Records. Ein Record ist ein Byte-Array, dessen Länge zwischen 1 und 255 Byte liegt. Alle Records müssen gleich lang sein. Eine linear fixed Datei kann maximal 254 Records enthalten. Jeder Record hat eine Nummer, unter deren Verwendung auf ihn zugegriffen werden kann. Auf einzelne Records kann wahlfrei zugegriffen werden, der Zugriff auf Teile eines Records ist jedoch nicht möglich. In dieser Dateistruktur werden typischerweise Daten mit ungefähr gleicher Länge gespeichert, zum Beispiel die geheimen Parameter p und q für das RSA-Verfahren.Auf einzelne Records kann wahlfrei zugegriffen werden, der Zugriff auf Teile eines Records ist jedoch nicht möglich. In dieser Dateistruktur werden typischerweise Daten mit ungefähr gleicher Länge gespeichert, zum Beispiel die geheimen Parameter p und q für das RSA-Verfahren. • Linear variable Die linear variable Dateistruktur ist analog zur linear fixed Dateistruktur aufgebaut, mit dem Unterschied, dass die einzelnen Records unterschiedliche Längen haben können. Sie findet vorzugsweise Verwendung für Speicherung der Daten mit sehr unterschiedlichen Längen, wie zum Beispiel die öffentlichen Parameter n und e beim RSA-Verfahren. • Cyclic Diese Dateistruktur basiert auf der Dateistruktur linear fixed. Zusätzlich enthält sie noch einen Zeiger, der immer auf den zuletzt geschriebenen Record zeigt. Wenn der Zeiger den letzten Record in der Datei erreicht, so wird er automatisch auf den ersten Record gesetzt. Enthält eine cyclic Datenstruktur n Records, so hat der letztgeschriebene Record die Nummer 1 und der älteste Record die Nummer n. In dieser Dateistruktur werden typischerweise Protokolle gespeichert, denn der älteste Eintrag wird durch den neusten überschrieben. 2.3. SMARTCARD 17 Der Dateideskriptor enthält in der Regel die folgenden Informationen: • Name der Datei (zum Beispiel FID=5103) • Dateityp (zum Beispiel EF) • Dateistruktur (zum Beispiel linear variable) • Dateigröße (zum Beispiel 2 Records mit einer Maximallänge von 129 Bytes) • Attribute (zum Beispiel Schlüsselfile für den öffentlichen RSA-Schlüssel) • Zugriffsbedingungen (zum Beispiel READ nach PIN-Überprüfung) • Verbindung zum Dateibaum (zum Beispiel im DF 4101) Der Standard PKCS#15 [RSAd] definiert, wie kryptographische Daten auf einer Smartcard zu speichern sind. PKCS#15 kann auf jeder ISO/IEC 7816 kompatiblen Karte realisiert werden. Der Standard zeichnet sich aus durch eine objektorientierte Vorgehensweise, wo Schlüssel, Zertifikate und andere Daten als Objekte mit Attributen und Werten behandelt werden. Damit Applikationen problemlos herausfinden, welche Objekte auf der Karte gespeichert und wie sie geschützt sind, sind verschiedene Kontainer (EFs) vorgesehen, welche Referenzen auf Objekte eines bestimmten Typs enthalten. So enthält zum Beispiel das AODF (Authenticate Object Directory File) Informationen über Objekte zu Authentifikation wie PIN. 2.3.6 Datenübertragung zur Smartcard Für die Kommunikation zwischen Smartcard und Terminal steht nur eine Leitung zur Verfügung. Dadurch können Informationen nur wechselseitig ausgetauscht werden. Dieses abwechselnde Senden und Empfangen wird als Halbduplex-Verfahren bezeichnet. Grundsätzlich reagiert die Smartcard immer auf Anfragen des Hosts, der entweder ein selbständiges Kartenterminal mit eigener Applikation oder ein von einem Computersystem angesteuerter Chipkartenleser ist. Sie sendet nie ohne äußeren Anstoß Daten. Es ergibt sich ein Master Slave Verhältnis, mit dem Host als Master und der Karte als Slave. Nach dem Einstecken der Chipkarte in ein Terminal werden als Erstes ihre belegten Kontakte elektrisch aktiviert. Daraufhin führt die Karte einen Power-On-Reset durch und sendet einen Answer to Reset (ATR) zum Terminal, der Karten- und Übertragungsparameter enthält. Nach der Auswertung des ATR sendet das Terminal ein erstes Kommandos. Die Smartcard bearbeitet das Kommando und erzeugt eine Antwort, die sie zum Terminal zurücksendet. Danach bleibt die Karte in einem Wartezustand, zu nächste Kommando des Terminals zu empfangen. Die Norm ISO/IEC 7816-3 definiert 15 Übertragungsprokolle, wovon sich zwei asynchrone Halbduplex-Protokolle international durchgesetzt haben. Sie werden als T=0 und 18 KAPITEL 2. GRUNDLAGEN T=1 bezeichnet. T=0 ist ein byteorientiertes Protokoll, das für jedes empfangene Byte dessen Paritätsbit prüft und im Falle eines Fehlers eine erneute Übertragung veranlasst. Das Protokoll T=1 arbeitet dagegen blockorientiert und genügt den Anforderungen der Schicht 1 Protokolle des OSI-Referenzmodells, wodurch es aber wesentlich komplexer ist. Als Übertragungseinheiten werden syntaktisch fest definierte APDUs (Application Protocol Data Units) verwendet. Die APDUs unterteilen sich in Command-APDUs (CAPDU), die Kommandos an die Chipkarte darstellen, und Response-APDUs (RAPDU), die die Antworten der Chipkarte darauf beinhalten. Die APDUs sind nach ISO/IEC 7816-4 so aufgebaut, dass sie für den Übertragungsprotokoll transparent sind, d.h. sie werden ohne Interpretation oder Veränderung übertragen. Die APDUs entsprechen den Dateneinheiten der Anwendungs Ein Command-APDU besteht aus einem Header und einem Body. Der Header setzt sich aus vier Bytes zusammen, Class (CLA), Instruction(INS) und Parameter 1 (P1) und 2 (P2). Das Class-Byte kennzeichnet Anwendungen und ihren spezifischen Befehlssatz. Kommandos nach ISO/IEC 7816-4 werden mit dem Class-Byte ’0X’ kodiert. Mit dem Instruction-Byte wird das eigentliche Kommando kodiert. In den Parameter-Bytes werden Optionen des Kommandos übergeben, zum Beispiel der Offset bei einem Dateizugriff. Abbildung 2.2: Der Aufbau einer Command-APDU. Der Body spezifiziert im Lc-Feld die Länge der Nutzdaten, dem die eigentlichen Daten des Kommandos folgen. Im Le-Feld wird die Länge der von der Karte zurückzusendenden Daten festgelegt. Wenn das Le-Feld den Wert ’00’ hat, wird das Maximum der für dieses Kommando zur Verfügung stehenden Daten in der Response-APDU erwartet. Der Body kann unterschiedliche Längen haben oder ganz fehlen, wenn das Datenfeld leer ist und keine Nutzdaten erwartet werden. Die von der Smartcard gesendete Response-APDU setzt sich aus einem optionalen Body und einem Trailer zusammen. Der Body enthält die Nutzdaten, deren Länge in der vorangegangenen Command-APDU festgelegt wurde. Der Trailer besteht aus zwei Bytes SW1 und SW2, die auch als Return-Code bezeichnet werden. Der Return-Code gibt Auskunft darüber, ob das Kommando erfolgreich ausgeführt wurde (Code ’9000’) oder ein 2.3. SMARTCARD 19 Fehler aufgetreten ist. Im letzten Fall enthält der Return-Code eine Fehlerkodierung. Abbildung 2.3: Der Aufbau einer Response-APDU. 2.3.7 Kommandos von Smartcards Smartcard-Betriebssysteme richten sich nach der ISO/IEC-Norm 7816 und stellen in der Regel die meisten dort festgelegten Kommandos zur Verfügung. Die Tabelle 2.1 gibt eine Übersicht über die wichtigsten Smartcard-Kommandos, welche in folgende Gruppen unterteilt werden können: • Kommandos zur Verwaltung von Dateien (SELECT FILE, CREATE FILE, DELETE FILE) • Lese- und Schreibkommandos (READ BINARY, UPDATE BINARY, READ RECORD, UPDATE RECORD, APPEND RECORD) Diese Kommandoklasse unterstützt die Verwendung einer Smartcard als sicheren Datenspeicher. Mit Hilfe dieser Kommandos lassen sich Informationen in ein EF schreiben und später wieder auslesen, wobei die Zugriffsbedingungen kontrolliert werden. Für unterschiedliche Dateistrukturen gibt es unterschiedliche Kommandos. • Kommandos zur Authentifikation Zu dieser Klasse gehören Kommandos für: – Authentifikation des Benutzers der Karte durch Überprüfung der PIN (VERIFY PASSWORD, CHANGE PASSWORD, UNBLOCK PASSWORD) – Authentifikation der Smartcard und des Terminals (ASK RANDOM, INTERNAL AUTHENTICATE, EXTERNAL AUTHENTICATE). • Kommandos für kryptographische Algorithmen Die kryptographische Funktionalität ist auf zwei Kommandos verteilt. Mit dem Kommando MANAGE SECURITY ENVIROMENT (MSE) werden vor der Ausführung eines kryptographischen Algorithmus die Parameter eingestellt. Danach wird der Algorithmus mit dem Kommando PERFORM SECURITY OPERATION (PSO) ausgeführt. Mit diesem Kommando lassen sich folgende Operationen ausführen: 20 KAPITEL 2. GRUNDLAGEN – Berechnung kryptographischer Prüfsummen (MAC) – Berechnung von Hash-Werten – Berechnung und Verifikation digitaler Signaturen – Ver- und Entschlüsselung der Daten. Kommando Funktion INS Byte Norm SELECT FILE Auswahl einer Datei A4 ISO/IEC 7816-4 CREATE FILE Erzeugen einer neuen Datei E0 ISO/IEC 7816-9 DELETE FILE Löschen einer Datei E4 ISO/IEC 7816-9 READ BINARY Lesen aus einer Datei mit transparenter Struktur B0 ISO/IEC 7816-4 UPDATE BINARY Schreiben in eine Datei mit transparenter Struktur D6 ISO/IEC 7816-4 READ RECORD Lesen aus einer Datei mit recordorientierter Struktur B2 ISO/IEC 7816-4 APPEND RECORD Einfügen eins neuen Records in eine Datei mit recordorientierter Struktur E2 ISO/IEC 7816-4 UPDATE RECORD Schreiben in eine Datei mit recordorientierter Struktur DC ISO/IEC 7816-4 VERIFY PASSWORD Überprüfen der PIN 20 ISO/IEC 7816-8 CHANGE PASSWORD Ändern der PIN 24 ISO/IEC 7816-8 UNBLOCK PASSWORD Zurücksetzen des abgelaufenen Fehlbedienungszählers der PIN 2C ISO/IEC 7816-8 ASK RANDOM / GET GHALLENGE Anforderung einer Zufallszahl von der Chipkarte 84 ISO/IEC 7816-4 INTERNAL CATE AUTHENTI- Authentifizierung der Chipkarte gegenüber dem Terminal 88 ISO/IEC 7816-4 EXTERNAL AUTHENTICATE Authentifizierung des Terminals gegenüber der Chipkarte 82 ISO/IEC 7816-4 MANAGE SECURITY ENVIROMENT Ändern der Parameter für die Benutzung kryptographischer Algorithmen der Chipkarte 22 ISO/IEC 7816-8 PERFORM SECURITY OPERATION Ausführen eines kryptographischen Algorithmus in der Chipkarte 2A ISO/IEC 7816-8 Tabelle 2.1: Die wichtigsten Smartcard-Kommandos nach ISO/IEC 7816. 2.3. SMARTCARD 2.3.8 21 Sicherheit Benutzerauthentifikation Der Benutzer authentifiziert sich gegenüber der Smartcard durch die Eingabe einer Geheimzahl, welche als PIN (Personal Identification Number) oder CHV (Card Holder Verification) bezeichnet wird. Die PIN ist meist eine vier- bis achtsstellige Zahl, die vom Benutzer am Terminal eingegeben wird. Das Terminal sendet dann die eingegebene PIN mit dem Kommando VERIFY PASSWORD an die Karte, wo sie mit der im EEPROM gespeicherten PIN verglichen wird. Daneben führt der Chip noch einen Zähler über die Anzahl der Fehlversuche, der als Fehlbedienungszähler (FBZ) bezeichnet wird. Wenn eine festgelegte Maximalzahl erreicht wird, wird die Karte gesperrt. Üblicherweise ist dies nach drei Fehlversuchen der Fall. Manche Karten ermöglichen das Entsperren durch die Eingabe der PUK (PIN Unblocking Key). Wenn die Anzahl der Fehlversuche bei der PUK-Eingabe den Maximalwert erreicht hat, wird die Karte endgültig gesperrt. Viele Anwendungen verwenden die sogennanten Transport-PINs. Die Smartcard wird mit einer zufälligen PIN personalisiert, die der Benutzer in einem PIN-Brief enthält. Bei der ersten Benutzung wird ein PIN-Wechsel erzwungen. Ein Spezialfall ist das NullpinVerfahren, bei dem die Transport-PIN sich nur aus Nullen zusammensetzt. Authentifikation der Karte und des Zielsystems Zur Authentifikation der Smartcard gegenüber dem Zielsystem wird ein Challenge-Response-Verfahren verwendet, wobei als symmetrisches Verfahren meist DES oder TripelDES und als asymmetrisches Verfahren meist RSA eingesetzt wird. Mit dem Kommando INTERNAL AUTHENTICATE kann die Hostanwendung jederzeit ein Authentifikationskryptogramm von der Chipkarte anfordern. Soll sich auch das Zielsystem gegenüber der Smartcard authentifizieren, so wird dazu wiederum ein Challenge-Response-Protokoll abgewickelt. Die Zufallszahl (Challenge) kann von der Karte mit dem Kommando ASK RANDOM angefordert werden. Unmittelbar danach sendet die Hostanwendung ein Authentifikationskryptogramm mit dem Kommando EXTERNAL AUTHENTICATE. Secure-Messaging Wenn der Datenaustausch zwischen Terminal und Smartcard ungesichert stattfindet, ist es durch elektrische Isolierung der Kontaktfelder der Karte und entsprechend angebrachte Drähte möglich, die Daten auf der I/O-Leitung beliebig zu manipulieren. Die Gegenmaßnahme zu diesem seit 1990 bekannten Angriff [Wolge] war die Einführung von SecureMessaging, verschiedener Mechanismen und Verfahren, welche die Authentizität und Vertraulichkeit der Datenübertragung garantieren. 22 KAPITEL 2. GRUNDLAGEN Für die gesicherte Datenübertragung benötigt man einen kryptographischen Algorith- mus, einen Schlüssel und bei Bedarf Initialdaten. Diese Parameter können für jede Kommunikationsrichtung verschieden sein und werden mit dem Kommando MANAGE SECURITY ENVIROMENT festgelegt. Zur Gewährleistung der Authentizität der Nachrichten werden kryptographische Prüfsummen (MAC) verwendet. Vertraulichkeit wird durch Verschlüsselung erreicht. Im Class-Byte des Kommandos wird angegeben, ob Secure-Messaging für das Kommando benutzt wird, ob es sich dabei um das Verfahren nach ISO/IEC 7816-4/6 handelt und ob der Header in die MAC-Berechnung mit eingeschlossen ist. Angriffe Angriffe auf Chipkarten lassen sich in drei verschiedene Arten einteilen: Angriffe über die soziale Ebene, die logische Ebene und die physikalische Ebene [Wolge]. Angriffe über die soziale Ebene sind an die Menschen gerichtet, die mit der Karte umgehen, und sind aus den herkömmlichen Umgebungen bekannt. Zum Beispiel kann der Angreifer versuchen, die PIN beim Eintippen an einer Tastatur auszuspähen. Die bekanntesten Angriffe über die logische Ebene sind Simple Power Analysis (SPA) und Differential Power Analysis (DPA), die darauf abzielen, den Stromverbrauch bei der Ausführung von Kommandos in der Chipkarte zu messen. Bei Smartcards gibt es häufig Abhängigkeiten des Stromverbrauchs von den verarbeiteten Daten. Man versucht die geheimen Schlüssel zu ermitteln, indem der Stromverbrauch zuerst bei der Verarbeitung bekannter Daten und dann bei der Verarbeitung unbekannter Daten gemessen wird. Auf der physikalischen Ebene versuchen die Angreifer, durch zu hohe bzw. zu niedrige Temperaturen oder durch Anlegen einer unüblichen Spannung den Mikrokontroller in seiner Funktionsweise zu manipulieren. Mit gezielten Störungen der Spannungs- und Taktversorgung wird es versucht, Änderungen im Code vorzunehmen und die geheimen Schlüssel zu ermitteln. Ein weiterer Angriff betrifft die Herauslösung des Chips aus dem Kartenkörper, sodass es mit Hilfe von Mirkoprobenadeln möglich ist, Signale auf den Bussen des Mikroprozessors abzuhören. Für eine Übersicht über die Angriffe auf Chipkarten mit mehr Details wird auf das Buch [Wolge] verwiesen. Kapitel 3 Selbstbediente Smartcard-Systeme Um Design und Implementierung der Software verstehen zu können, muss zuerst das Umfeld vorgestellt werden, im dem die Arbeit entstanden ist. Dazu gehören selbstbediente Smartcard-Systeme, die ein Anwendungsgebiet des Frameworks darstellen. Im diesem Kapitel werden zwei bestehende selbstbediente Smartcard-Systeme, FlexiTrust Identity Management und TUDCard, vorgestellt. Eine beispielhafte Analyse dieser Systeme im Kapitel 6 wird es gestatten, genaue Anforderungen an die Software zu ermitteln, die selbstbediente Verfahren unterstützt. 3.1 FlexiTrust Identity Management FlexiTrust Identity Management erweitert die Trustcenter-Software FlexiTrust [Fle] und übernimmt im Rahmen einer PKI sämtliche Aufgaben, die mit Personalisierung und Verwaltung von Smartcard-PSEs verbunden sind. Damit lässt sich eine dezentrale und flexible Smartcard-Infrastuktur aufbauen, in der der Rollout selbstbedient durch die Benutzer abgewickelt wird. Der Aufwand wird minimiert und die PKI-Prozesse werden erheblich vereinfacht. Damit ermöglicht FlexiTrust Identity Management eine einfache Integration von hochsicheren PKIs mit Smartcard- Geheimnisträgern in jede Arbeitsumgebung, bringt Kostenersparnis und Investitionssicherheit. Mit FlexiTrust Identity Management lassen sich im Rahmen einer PKI folgende Aufgaben erledigen: • Selbstbediente Personalisierung von Smartcards • Selbstbedientes Erneuern von Smartcards • Erstellung einer Notfallkarte • Selbstbedientes Entsperren der Karte und Neusetzen der PIN • Selbstbedientes Löschen der Karteninhalte 23 24 KAPITEL 3. SELBSTBEDIENTE SMARTCARD-SYSTEME • Verwaltung von Smartcards, Benutzerkonten und Zertifikaten Das System arbeitet mit CardOS und TCOS Smartcards. 3.1.1 Anwendungsszenarien Mögliche Anwendungsszenarien für FlexiTrust Identity Management Smartcards, die selbstverständlich auch untereinander kombiniert werden können, sind: • Sichere Email (digitale Signatur und Verschlüsselung) • Datenverschlüsselung Mit Smartcard-basierter Verschlüsselung bleiben sensible Daten sicher geschützt. Wenn die Smartcard vergessen wird, verloren geht oder gestohlen wird, muss der legitime Benutzer trotzdem auf die Daten zugreifen können. Zu diesem Zweck bietet FlexiTrust Identity Management ein Key-Backup für Verschlüsselungsschlüssel. • Windows-Smartcard-Logon FlexiTrust Chipkarten werden mit einem Windows-Logon Zertifikat ausgestattet, womit ein Logon an Windows 2000 und WindowsXP Rechnern möglich ist. Statt den Benutzernamen und das Passwort einzugeben, steckt der Benutzer einfach seine Smartcard ein und gibt die PIN ein, um sich anzumelden. Der Vorteil dieser Lösung ist, dass der Benutzer sich keine Windows-Passwörter merken muss. • Kobil SecOVID Smartcard FlexiTrust Smartcards können auch im Rahmen von Kobil SecOVID System [KOB] zur Generierung von Einmalpasswörtern eingesetzt werden. Dazu wird bei der Kartenpersonalisierung SecOVID OTP (One Time Password) Generator auf die Karte geschrieben. Will sich ein Benutzer bei einem System anmelden, so muss er zum Nachweis seiner Identität das für ihn augenblicklich gültige Einmalpasswort eingeben. Dieses kennt zunächst selbst der Benutzer nicht. Er hat seine SecOVID-Chipkarte zu fragen, woraufhin er zunächst seine geheime PIN am Kartenleser eingeben muss. Ist die PIN korrekt, wird das Einmalpasswort berechnet und im Display des Kartenlesers angezeigt. Jedes Passwort wird nur ein einziges Mal vom System akzeptiert (Einmalpasswort), so dass der Benutzer beim nächsten Anmeldevorgang erneut eine Anfrage an seine Chipkarte zu starten hat. Kobil SecOVID kann für sicheres lokales Login in einem Firmennetzwerk eingesetzt werden. Das System eignet sich hervorragend auch für sicheres remote Login für Außendienstmitarbeiter und Kunden. Die Benutzerauthentifikation einer Firewall, einem Einwahlsystem oder einem VPN gegenüber wird entscheidend gestärkt. 3.1. FLEXITRUST IDENTITY MANAGEMENT 3.1.2 25 Software-Architektur FlexiTrust Identity Management erweitert die Trustcenter-Software FlexiTrust um folgende Komponenten: • Anmeldeserver mit Benutzerschnittstelle Der Anmeldeserver ist das Eingangsportal für die PKI-Teilnehmer: Nach einer Anmeldung kann der Benutzer selbstbediente Smartcard-Operationen ausführen. Dafür wird eine ActiveX-Control-Komponente vom Browser des Benutzers runtergeladen. Alle Daten zwischen dem Client-Rechner und dem Anmeldeserver werden SSLverschlüsselt übertragen. • Smartcard-Operationen auf dem Rechner des Benutzers Folgende Operationen können auf dem Client-Rechner von der ActiveX-ControlKomponente ausführt werden: – Initialisierung der Chipkarte – PIN/PUK mit dem Fehlbedienungszähler schreiben – Verschlüsselungszertifikat bzw. Schlüsselbackup einspielen – PIN verifizieren – Kartenseriennummer auslesen – Personalisierungsstatus der eingelegten Chipkarte feststellen (leer oder initialisiert) – PIN der Chipkarte unter Benutzung der PUK zurücksetzen – Komplette Karte mit Hilfe der PUK löschen. Dabei werden PIN, PUK, und alle Daten gelöscht. Die Karte kann dann wieder neu personalisiert werden, wie im Urzustand. • Datentransport Eine zusätzliche Komponente ist für den Datentransport zwischen dem Anmeldeserver und der Trustcenter-Datenbank zuständig. Außerdem beantragt sie die Benutzerzertifikate bei FlexiTrust-RA und liefert ausgestellte Zertifikate zurück. • Verwaltungskonsole Die Verwaltung von Benutzer- und Administratorkonten, Chipkarten, Zertifikaten und Sperrlisten wird dadurch erheblich vereinfacht. 26 KAPITEL 3. SELBSTBEDIENTE SMARTCARD-SYSTEME 3.1.3 Smartcard-Prozesse Um selbstbediente Smartcard-Operation ausführen zu können, müssen sich die Benutzer auf dem Anmeldeserver mit Benutzername, Passwort und TAN (einmalige Transaktionsnummer) anmelden. Jede TAN ist an einen Verwendungszweck gebunden. Wenn der Benutzer schon eine Karte hat und es sich um einen Prozess handelt, bei dem es wichtig ist, dass sich die richtige Karte im Kartenleser befindet (Löschen der Karte, PIN-Reset), ist die TAN zusätzlich noch an die Smartcard-Seriennummer gebunden. Außerdem ist die Gültigkeitsdauer einer TAN begrenzt. Für ein Benutzerkonto darf immer höchstens eine TAN freigeschaltet sein. Die Benutzer bekommen ihre TANs über einen sicheren Kanal, in einem TAN-Brief oder über eine geschützte Webseite, auf die nur per Smartcard zugegriffen werden kann. Neue Karte (selbstbediente Kartenpersonalisierung) Bei FlexiTrust Identity Management wird die Kartenpersonalisierung durch die Benutzer realisiert und läuft wie folgt ab: 1. Der Benutzer erhält zunächst eine leere Smartcard (weder PIN noch PUK sind gesetzt) und seine Authentifikationsdaten über einen vertraulichen Kanal. 2. Nach einer erfolgreichen Anmeldung auf dem Anmeldeserver erscheint eine Seite mit der ActiveX-Control-Komponente, in der die neue PIN der Karte angezeigt wird. Hier können auch weitere Informationen und Belehrungen zur Karte stehen. Die PUK wird nicht angezeigt, aber zentral gespeichert. Aus Sicherheitsgründen sollte der Benutzer die PUK nicht kennen (nach drei Falscheingaben der PUK ist die Karte unbrauchbar). 3. Auf der Seite steht ein Karte personalisieren“ Button, der den Personalisierungs” prozess über die ActiveX-Control-Komponente in einem Schritt für den Benutzer durchführt: (a) Ist die Seriennummer der Karte dem System bekannt, wird die Karte zuerst vollständig gelöscht. (b) PIN und PUK mit FBZ werden gesetzt. (c) Die Schlüsselpaare für Signatur und Windows Smartcard Logon werden in der Karte erzeugt und PKCS#10-Zertifikatsanträge [RSAa] werden erstellt. (d) Die Datentransport-Komponente importiert die Anfragedaten in die TrustcenterDatenbank und schickt die Zertifikatsanträge mit weiteren Daten in signierten PKSC#7-Dateien [RSAe] zu FlexiTrust-CA. 3.1. FLEXITRUST IDENTITY MANAGEMENT 27 Außerdem können in diesem Schritt weitere Geheimnisse und Daten, die für verschiedene Anwendungen erforderlich sind (zum Beispiel Kobil SecOVID OTP Generator oder Daten für eigene Verfahren), auf die Karte geschrieben werden. 4. Da für das Verschlüsselungsschlüsselpaar ein Key-Recovery erwünscht ist, wird es in der FlexiTrust-CA erzeugt. Außerdem erstellt FlexiTrust-CA drei Zertifikate (Signatur, Verschlüsselung und Windows Smartcard Logon). Das Verschlüsselungszertifikat und das Schlüsselpaar werden als .p12-Datei [RSAc] gesichert hinterlegt (Key Backup). 5. Die Zertifikate werden veröffentlicht und von der Datentransport-Komponente auf einer Import-Webseite ausgeliefert. Für den Benutzer wechselt danach die Webseite zur Import-Seite, wo die Zertifikate in einem Schritt von der ActiveX-ControlKomponente auf die Karte eingespielt werden. Ersatzkarte (selbstbedientes Erneuern von Smartcards) Falls eine Smartcard aus einem nicht sicherheitskritischen Grund nicht mehr benutzbar ist (zum Beispiel wenn die Karte defekt ist oder wenn das Signatur- oder Windows Logon Zertifikat abläuft), kann der Benutzer eine Ersatzkarte für sich ausstellen. Dafür erhält er eine leere Smartcard oder löscht vollständig seine Vorgängerkarte. Dann wird die Karte neu personalisiert (s. Abschnitt 3.1.3), wobei ein Key-Recovery für den Verschlüsselungsschlüssel und das entsprechende Zertifikat stattfindet. Alle anderen Daten (Schlüsselpaare, Zertifikate, Geheimnisse und Applikationsdaten) werden neu generiert und auf die Smartcard geschrieben. Notfallkarte Um reibungsloses Arbeiten zu ermöglichen, unterstützt FlexiTrust Identity Management Ausstellung einer Notfallkarte für vergessene oder verlegte Karten. Eine Notfallkarte wird vom PKI-Administrator erstellt und hat eine kurze Gültigkeitsdauer. Sie wird personalisiert wie eine Ersatzkarte, d.h. das gesicherte Verschlüsselungszertifikat der Original-Karte sowie ein neu generiertes Signaturzertifikat und Windows Logon Zertifikat werden auf die Karte eingespielt. Notfallkarten müssen nach dem Ablauf ihrer Gültigkeit zurückgegeben werden. Sie werden dann vom PKI-Administrator deaktiviert und vollständig gelöscht. PIN-Reset (selbstbedientes Entsperren der Karte) Die PIN ist durch einen Fehlbedienungszähler geschützt, d.h. nach einigen aufeinander folgenden Falscheingaben wird die Karte gesperrt und kann nur mit der PUK entsperrt 28 KAPITEL 3. SELBSTBEDIENTE SMARTCARD-SYSTEME werden. Aus Sicherheitsgründen kennt der Benutzer die PUK nicht, ist aber trotzdem in der Lage, die Karte zu entsperren und die PIN neu zu setzen: 1. Der Benutzer meldet sich auf dem Anmeldeserver mit seinem Benutzernamen, Passwort und einer TAN für den Prozess PIN Reset“ an. ” 2. Es wird überprüft, ob die an die TAN gebundene Smartcard-Seriennummer mit der Seriennummer der Chipkarte übereinstimmt. 3. Ist die Prüfung erfolgreich, wird die Karte von der ActiveX-Control-Komponente mit Hilfe der PUK entsperrt und die neue PIN wird im Browser angezeigt. Der FBZ der PIN wird dabei zurückgesetzt. Selbstbedientes Löschen der Karte FlexiTrust Identity Management ermöglicht selbstbedientes Löschen aller Karteninhalte, inklusive PIN und PUK. Nach dem Löschen ist die Karte leer und kann neu personalisiert werden, wie im Urzustand. 1. Der Benutzer meldet sich auf dem Anmeldeserver mit seinem Benutzernamen, Passwort und einer TAN für den Prozess Karte Löschen“ an. ” 2. Es wird überprüft, ob die an die TAN gebundene Smartcard-Seriennummer mit der Seriennummer der Chipkarte übereinstimmt. 3. Ist die Prüfung erfolgreich, wird die Karte von der ActiveX-Control-Komponente mit Hilfe der PUK gelöscht. Dabei werden alle Daten auf der Karte sowie PIN und PUK mit Fehlbedienungszählern gelöscht. 3.2 TUDCard Ab dem Wintersemester 2005/2006 wurde an der TU Darmstadt für alle Studierenden die TUDCard eingeführt [tuda], die sowohl als digitale Identität und zugleich als elektronische Geldbörse genutzt werden kann. Die digitale Identität ermöglicht den Zugang zu allen studienrelevanten elektronischen Ressourcen der Universität. Allgemein soll damit ein sicherer und bequemer Zugang zum Internet, zu den Rechnern in den PC-Pools sowie zu einer Reihe von Webapplikationen und -inhalten verwirklicht werden. Daneben können Dateien oder Emails mit einer digitalen Signatur versehen werden. Die TUDCard ist in der Abbildung 2.1 dargestellt. Dabei handelt es sich um eine Hybridkarte (s. Abschnitt 2.3.1), mit einem kontaktbehafteten TCOS-Chip und einem kontaktlosen Mifare-Chip ausgestattet ist. Der Mifare-Chip wird für bargeldlose Zahlungen in der Mensa und in Zugangskontrollsystemen benutzt. Die digitale Identität wird über ein Signaturzertifikat auf dem TCOS-Chip realisiert. 3.2. TUDCARD 3.2.1 29 Anwendungsszenarien Die möglichen kryptographischen Anwendungen der TUDCard sind: • Sichere Email (digitale Signatur und Verschlüsselung) • Windows-Smartcard-Logon in PC-Pools (s. Abschnitt 3.1.1) • Mobiler Internet-Zugang mit Cisco VPN-Client • Zugang zu geschützten Webseiten per SSL • Elektronische Anmeldung zu Lehrveranstaltungen • Elektronische Prüfungsverwaltung (An- und Abmeldung, Noteneinsicht) • Digitaler Bibliothekausweis Für eine detaillierte Beschreibung der TUDCard-Anwendungen wird auf die Diplomarbeit [Her05] verwiesen. 3.2.2 Einrichtung der TUDCard Bei der Einrichtung der TUDCard werden einige Smartcard-Prozesse selbstbedient durch die Benutzer ausgeführt. Dadurch wird der Aufwand minimiert und die PKI-Abläufe werden erheblich vereinfacht. Eine dezentrale und flexible Smartcard-Rollout-Infrastruktur wird mit Hilfe einer zusätzlichen Software-Komponente, Card Manager [Isk05], aufgebaut. Card Manager ermöglicht die Realisierung folgender Aufgaben: • Selbstbediente Freischaltung und Initialisierung von Smartcards • Selbstbedientes Erneuern des Zertifikats • Selbstbedientes Entsperren der Karte und Neusetzen der PIN • Selbstbedientes Ändern der PIN Die selbstbedienten Smartcard-Prozesse stellen ein Schritt in der Einrichtung der TUDCard für einen Studierenden dar und gehören zu der Kette der Abläufe in der PKI der TUD. Um sie besser verstehen zu können, werden im folgenden die Smartcard-relevanten PKI-Abläufe kurz skizziert. Der Kartenhersteller liefert die benötigte Anzahl von Chipkarten an die TU Darmstadt. Die Karten sind vorbeschlüsselt, d.h. auf jeder Karte befindet sich ein Schlüsselpaar, die PUK und die versteckte PUK (eine mit der PIN geschützte Kopie der PUK). Außerdem ist das Nullpin-Verfahren (s. Abschnitt 2.3.8) der Karte aktiviert. Die Zuordnung von Kartenseriennummern zu öffentlichen Schlüssel wird auch mitgeliefert. Jedem Studenten 30 KAPITEL 3. SELBSTBEDIENTE SMARTCARD-SYSTEME wird eine Karte und damit auch ein öffentlicher Schlüssel zugeordnet. Nun kann ein Zertifikat für den Studenten von der CA der TUD erstellt werden. Das erstellte Zertifikat ist ein X.509-Zertifikat, das mit dem öffentlichen Schüssel des Studenten verschlüsselt und im LDAP-Verzeichnis publiziert wird. Danach wird die Karte dem Studenten per Post zugesandt. 3.2.3 Smartcard-Prozesse Um selbstbediente Smartcard-Prozesse durchführen zu können, muss der Benutzer zuerst auf seinem Rechner Card Manager starten, der als Java WebStart Applikation verfügbar ist. Selbstbediente Freischaltung und Initialisierung Nachdem die TUDCard in den Kartenleser eingeführt wurde, wird von Card Manager als erstes überprüft, ob die Karte sich im Nullpin-Status befindet. Nur in diesem Fall wird mit der Freischaltung der Karte fortgefahren: 1. Der Benutzer authentifiziert sich mit seinem Benutzernamen und Passwort für das Hochschulnetz. 2. Es wird überprüft, ob das Benutzerzertifikat im LDAP-Verzeichnis veröffentlicht wurde. Ist es nicht der Fall, kann die Karte nicht initialisiert werden. Der Vorgang wird mit einer Fehlermeldung abgebrochen. 3. Die PIN der Karte wird gesetzt. Dazu wird der Benutzer aufgefordert, die Nullpin (’000000’) und zweimal seine neue sechstellige PIN über den Kartenleser einzugeben. 4. Die versteckte PUK wird ausgelesen und angezeigt. Dafür muss die neu gesetzte PIN eingegeben werden, weil die versteckte PUK mit der PIN geschützt ist. Anschließend wird die versteckte PUK von der Karte gelöscht. Der Benutzer soll sich diese PUK merken, weil es keine andere Möglichkeit besteht, die PUK anzuzeigen. 5. Das Zertifikat des Benutzers wird auf die Karte übertragen, wo es mit dem privaten Schlüssel entschlüsselt wird. Dazu muss die PIN eingegeben werden. Anschließend wird das Zertifikat in entschlüsselter Form auf die Karte und zurück in das LDAPVerzeichnis geschrieben. Nachdem die Karte freigeschaltet wurde, können die anderen selbstbedienten Operationen ausgeführt werden. 3.2. TUDCARD 31 Selbstbedientes Erneuern des Zertifikats Wenn das Zertifikat auf der Karte nicht mehr verwendbar ist (zum Beispiel weil es abgelaufen ist oder gesperrt wurde), kann ein neues Zertifikat selbstbedient auf die Karte eingespielt werden. Dies läuft wie folgt ab: 1. Der Benutzer authentifiziert sich mit seinem Benutzernamen und Passwort für das Hochschulnetz. 2. Es wird überprüft, ob das neue Zertifikat im LDAP-Verzeichnis veröffentlicht wurde. Ist es nicht der Fall, wird der Vorgang mit einer Fehlermeldung abgebrochen. 3. Das Zertifikat wird auf die Karte übertragen, wo es nach einer PIN-Eingabe mit dem privaten Schlüssel entschlüsselt wird. Anschließend wird das Zertifikat in entschlüsselter Form auf die Karte und zurück in das LDAP-Verzeichnis geschrieben. Selbstbedientes Entsperren der Karte und Neusetzen der PIN Wenn die PIN nach drei Falscheingaben gesperrt wurde, kann selbstbedient entsperrt werden. Dafür muss die PUK und zweimal eine neue PIN eingegeben werden. Der FBZ der PIN wird dabei zurückgesetzt. Selbstbedientes Ändern der PIN Die PIN der Karte kann durch den Benutzer geändert werden. Dafür muss die alte PIN und zweimal die neue PIN eingegeben werden. 32 KAPITEL 3. SELBSTBEDIENTE SMARTCARD-SYSTEME Kapitel 4 Standardisierte Smartcard-Schnittstellen Um Chipkarten im Rahmen von Sicherheitsinfrastrukturen einsetzen zu können, braucht man die Unterstützung durch die Software des PCs. In der Vergangenheit war die Erstellung terminalunabhängiger Anwendungen problematisch, weil jedes Terminal seine eigene Softwareschnittstelle hatte. Mitte der 90er begannen Spezifikationsarbeiten für Schnittstellen zur terminalunabhängigen Anbindung von Smartcards in PC-Programme. Heutzutage sind die wichtigsten davon PKCS#11, PC/SC, OCF und CT-API. Da das entwickelte Framework sich auf diese Schnittstellen stützt, werden sie in diesem Kapitel vorgestellt. 4.1 PKCS#11 Public Key Cryptography Standard #11 wurde von RSA Laboratries spezifiziert [RSAb] und beschreibt eine C-Schnittstelle zum Ansprechen von Geräten mit kryptographischer Funktionalität. Dabei handelt es sich um eine High-Level-Schnittstelle, die vom SmartcardBetriebssystem und Smartcard-Kommandos (vgl. Abschnitt 2.3.7) abstrahiert. Vom Hersteller wird eine Bibliothek mitgeliefert, welche die Befehle des Standards unterstützt und transparent für die darauf aufbauende Applikation in die Kommandos der Karte und des Lesers übersetzt. Das hohe Abstraktionsniveau ist ein wesentlicher Vorteil von PKCS#11. PKCS#11 ist die älteste und die verbreitetste von den beschriebenen Schnittstellen. Es gibt stabile Bibliotheken von verschiedenen Herstellern. Das ist de facto Standard für übliche Clients wie Thunderbird, Mozilla oder Netscape Communicator. Der Hauptnachteil von PKCS#11 ist, dass eine Bibliothek für eine bestimmte Kombination Smartcard-Kartenleser geschrieben wird. Wenn ein System m verschiedene Kartenleser und n verschiedene Chipkarten unterstützen soll, so müssen m ∗ n Bibliotheken installiert werden. Abgesehen von dem großen Aufwand ist es nicht selbstverständlich, dass es die nötigen Bibliotheken überhaupt gibt. 33 34 KAPITEL 4. STANDARDISIERTE SMARTCARD-SCHNITTSTELLEN Eine PKCS#11-Bibliothek implementiert eine feste, im Standard definierte Menge von High-Level Smartcard-Funktionen. Einerseits ist dies vorteilhaft, weil dem Entwickler fertige Implementierungen komplizierter Funktionen zur Verfügung stehen. Dadurch werden Entwicklungszeiten erheblich verkürzt. Andererseits kann dies zu einem Nachteil werden, wenn man Funktionen braucht, die nicht zum Standard gehören, wie zum Beispiel die Unterstützung des Nullpin-Verfahrens. In diesem Fall ist man auf die Implementierung der benötigten Funktionen durch den Hersteller angewiesen oder es muss eine Hybrid-Lösung (PKCS#11 in Kombination mit einer anderen Schnittstelle) eingesetzt werden. Die Sicherheit von PKCS#11 ist nicht lückenlos. Im Paper [Jol03] werden einige Design-Schwächen des Standards und mögliche Attacken aufgezeigt. Um C-Funktionen der Bibliothek aus einer Java-Umgebung aufzurufen, wurde an der TU Darmstadt im Rahmen der Diplomarbeit von Vlad Coroama ein Java-PKCS#11Provider [Vla00] entwickelt. 4.2 PC/SC Personal Computer/ Smartcard (PC/SC) Standard wurde von PC/SC Workgroup entwickelt [pcsb] und spezifiziert eine C-Schnittstelle zur Interaktion zwischen Computersystemen und Chipkarten. Ein wesentlicher Vorteil von PC/SC gegenüber PKCS#11 ist, dass es eine Schnittstelle bietet, in der nur der Hersteller des Lesegeräts eine PC/SCBibliothek mitliefert. Dadurch wird viel an Flexibilität gewonnen. Wenn ein System n verschiedene Smartcards und m verschiedene Kartenleser unterstützen soll, so müssen nur m Bibliotheken installiert werden im Gegensatz zu m ∗ n bei PKCS#11. Außerdem wird dadurch Interoperabilität von Smartcards und Kartenlesern erhöht. Der Hersteller muss nur eine Bibliothek liefern, die für alle Kombinationen verwendet wird. Bei PC/SC handelt es sich um eine Low-Level-Schnittstelle, welche die Übermittlung von APDUs zur Smartcard übernimmt. Einerseits bedeutet dies, dass der Entwickler alle COS-Details verstehen muss und die Entwicklungszeiten im Vergleich zu PKCS#11 wesentlich länger sind. Außerdem besteht die Gefahr, dass mit jedem COS-Update die Applikation angepasst werden muss, weil benutzte Funktionen nicht mehr verfügbar sind. Andererseits eröffnet die APDU-Welt die Möglichkeit, die Smartcard-Funktionalität in vollem Umfang auszunutzen und Funktionen zu implementieren, die eigenen Bedürfnissen und Anforderungen genau entsprechen. Um PC/SC-Schnittstelle zu benutzen, muss ein PC/SC-Treiber für den Kartenleser installiert werden. Da der Standard weltweit hohe Verbreitung kennt, sind PC/SC-Treiber für die meisten Lesegeräte verfügbar. Um die PC/SC-Bibliothek aus einer Java-Umgebung anzusprechen, kann ein Java-Wrapper für PC/SC von IBM [jpc] verwendet werden. PC/SC wurde ursprünglich für Windows konzipiert, kann aber auf verschiedenen Plattformen eingesetzt werden. Vom Java-Wrapper [jpc] werden Windows- und Linux-Umge- 4.3. OCF 35 bungen unterstützt. Das Projekt MUSCLE [mus] bietet PC/SC-Kartenlesertreiber für Linux, Solaris und MacOSX. 4.3 OCF OpenCard Framework (OCF) wurde von OpenCard Consortium [ocf] ins Leben gerufen und ist ein Java-basiertes Framework zur Entwicklung von Smartcard-Anwendungen. Das Framework läuft auf jeder Java-fähigen Plattform und ist damit als solches unabhängig vom Betriebssystem des PC. Das ist ein großer Vorteil von OCF. Wie PC/SC, braucht OCF jeweils eine Bibliothek vom Smartcard-Hersteller und vom Hersteller des Kartenlesers (als CardServices und CardTerminals bezeichnet). Die Installation ist aber im Gegensatz zu PC/SC nicht trivial, weil zusätzlich zu den Bibliotheken noch das Framework selbst installiert werden muss. OCF bietet eine objekt-orientierte Smartcard-Schnittstelle, die Veränderungen in Hardware oder im Smartcard-Betriebssystem vor der Anwendung verbirgt. Das Framework definiert die Schnittstelle für die Anwendung als sogenannte CardServices. Die Implementierung eines CardService ist für die Anwendung transparent und kann jeder Zeit ausgetauscht werden. OCF hat sich zum Standard im Java-Umfeld etabliert, es ist gut dokumentiert und von umfangreichen Tutorials begleitet. OCF-Treiber existieren allerdings nur für wenige Kartenleser. Aus diesem Grund wurde ein OCF-Wrapper für PC/SC, ein PC/SCCardTerminal [pcsa], entwickelt, so dass OCF-Framework im sogenannten PassThru” Modus“ mit jedem PC/SC-Kartenlesertreiber benutzt werden kann. In diesem Fall agiert OCF-Framework als Java-Wrapper für PC/SC-Schnittstelle, d.h. man kann aus einer JavaUmgebung APDUs an die Smartcard senden. Durch die zusätzlichen Komponenten wird die Installation noch aufwendiger und benutzerunfreundlicher, unter anderem weil der Wrapper sich auf Java Comm API stützt. 4.4 CT-API Card Terminal Application Programming Interface (CT-API) wurde im Teil 3 des deutschen Standards MKT (Multifunktionales Kartenterminal) von Teletrust spezifiziert [mkt] und findet vor allem im deutschsprachigen Raum große Verbreitung. CT-API ist eine anwendungsunabhängige Schnittstelle für Terminals, sie ist unabhängig von einer Programmiersprache und prozedural aufgebaut. Es stehen nur 3 Funktionen zur Verfügung: • CT init für die Initialisierung der Verbindung zur Karte oder zum Terminal • CT data für den Datenaustausch auf einer bestehenden Verbindung 36 KAPITEL 4. STANDARDISIERTE SMARTCARD-SCHNITTSTELLEN • CT close zum Schließen der Verbindung. Diese ganz einfache Schnittstelle ermöglicht das Senden von APDUs zur Smartcard und zum Kartenleser. Für jede Kombination Karte-Lesegerät muss eine bestimmte APDUSequenz gesendet werden, um ihre Funktionen zu benutzen. Einfachheit ist der wichtigste Vorteil von CT-API. Kapitel 5 Anforderungsanalyse In diesem Kapitel werden Anforderungen an das zu entwickelnde Framework gestellt. Im ersten Teil werden die Smartcard-Servicefunktionen der vorgestellten selbstbedienten Systeme, FlexiTrust Identity Management und TUDCard, analysiert. Dies ermöglicht, funktionale Anforderungen an die Software zu ermitteln. Anschließend wird auf qualitative Anforderungen eingegangen. 5.1 5.1.1 Smartcard-Servicefunktionen bestehender Systeme Smartcard-Servicefunktionen von FlexiTrust Identity Management Die folgenden Smartcard-Funktionen werden benötigt (vgl. Abschnitt 3.1.3): • Für die Prozesse Neue Karte“, Ersatzkarte“und Notfallkarte“: ” ” ” – Kartenseriennummer auslesen – alte Daten auf der Karte vollständig löschen – PIN mit FBZ setzen – PUK mit FBZ setzen – zwei Schlüsselpaare auf der Karte erzeugen – ein Schlüsselpaar auf die Karte schreiben – PKCS#10-Zertifikatsanträge erstellen (dafür muss der öffentliche Schlüssel mit dem privaten signiert werden) – Zertifikate auf die Karte schreiben – eventuell weitere Daten/Applikationen auf die Karte bringen • Für den Prozess PIN Reset“: ” – Kartenseriennummer auslesen 37 38 KAPITEL 5. ANFORDERUNGSANALYSE – PUK verifizieren – PIN nach einer erfolgreichen Verifikation der PUK entsperren und neu setzen • Für den Prozess Karte Löschen“: ” – Kartenseriennummer auslesen – PUK verifizieren – nach einer erfolgreichen Verifikation der PUK alle Daten auf der Karte löschen 5.1.2 Smartcard-Servicefunktionen von TUDCard Es werden folgende Smartcard-Funktionen verwendet (vgl. Abschnitte 3.2.2 und 3.2.3): • Für selbstbediente Freischaltung und Initialisierung der Karte: – Kartenstatus auslesen (Nullpin oder initialisiert) – Transport-PIN ändern (Benutzer-PIN setzen) – PIN verifizieren – versteckte PUK auslesen – versteckte PUK löschen – Zertifikat entschlüsseln – Zertifikat auf die Karte schreiben • Für selbstbedientes Erneuern des Zertifikats: – PIN verifizieren – neues Zertifikat entschlüsseln – altes Zertifikat löschen – neues Zertifikat auf die Karte schreiben • Für selbstbediente PIN-Operationen: – PUK verifizieren – PIN nach einer erfolgreichen Verifikation der PUK entsperren und neu setzen – PIN verifizieren – PIN nach einer erfolgreichen Verifikation ändern • Für zentralisierte PKI-Abläufe (vorbeschlüsseln der Karte, Erzeugung des Zertifikats): – Kartenseriennummer auslesen 5.2. FUNKTIONALE ANFORDERUNGEN 39 – Nullpin-Status setzen – PUK mit FBZ setzen – Schlüsselpaar auf die Karte schreiben – öffentlichen Schlüssel auslesen 5.2 Funktionale Anforderungen Zwischen den verwendeten Smartcard-Funktionen in den beiden analysieren Systeme lassen sich viele Gemeinsamkeiten feststellen, die auch auf andere Smartcard-Systeme übertragen werden können. Im allgemeinen kann man die benötigten Servicefunktionen in folgende Gruppen einteilen: 1. Auslesen öffentlicher Informationen von der Karte Wenn eine Smartcard in das Lesegerät eingesteckt wird, ist sie erstmal ein black ” box“ für die Smartcard-Applikation. Dem System liegen noch keinerlei Informationen über diese Smartcard vor. Es ist zum Beispiel nicht bekannt, ob die Karte initialisiert ist, also ob die PIN gesetzt ist oder nicht. Ob und welche Daten sich auf der Karte befinden, ist auch unbekannt. Ohne diese Informationen ist es nicht möglich, die Smartcard korrekt zu bedienen. So wie eine CD-ROM vor der Benutzung gelesen werden muss, müssen zuerst die öffentlichen Informationen von der Chipkarte auslesen werden. Dann kann die Entscheidung getroffen werden, welche Operationen im aktuellen Kartenzustand möglich und zugelassen sind. Die Funktionen zum Auslesen von Karteninformationen sind also für eine korrekte Ausführung aller anderen Smartcard-Operationen notwendig. Wichtige Funktionen aus dieser Gruppe sind: • Kartenseriennummer auslesen • Kartenstatus ermitteln (initialisiert oder nicht) • Zertifikat von der Karte auslesen • Öffentliche Schlüssel auslesen • Anzahl und Typ der Schlüssel und Zertifikate auf der Karte ermitteln Besonders wichtig für ein System, in dem mehrere Schlüsselpaare für verschiedene Zwecke (zum Beispiel Signatur und Verschlüsselung) oder Verfahren (RSA und DSA) auf die Karte gebracht werden. • FBZ-Status der PIN und der PUK auslesen Nützlich, um Angriffe zu erkennen, die zum Ziel haben, Passwörter der Karte (PIN und PUK) auszuspähen. Ohne FBZ wäre es leicht, selbst sechstellige Passwörter durch Brute Force Attack (exhaustive search) zu ermitteln. 40 KAPITEL 5. ANFORDERUNGSANALYSE Mit einem Fehlbedienungszähler hat der Angreifer nur einige wenige (meist drei) Eingabemöglichkeiten, bevor die Karte gesperrt wird. Der Angreifer kann aber versuchen, nach zwei Falscheingaben die Karte wieder in den Normalbetrieb einzuführen, damit der legitime Benutzer durch die Eingabe der korrekten PIN/PUK den Zähler auf seinen Startwert zurücksetzt. Bei dem nächsten Angriff auf diese Karte hätte der Angreifer wieder zwei Freiversuche. Wenn der FBZ-Status regelmäßig ausgelesen wird, kann der Angriff erkannt werden. 2. Personalisierung der Karte In jeder Sicherheitsinfrastruktur müssen Smartcards personalisiert werden, d.h. PIN muss gesetzt und Benutzerdaten (Schlüssel und Zertifikate) auf die Karte geschrieben werden. Die Kartenpersonalisierung nimmt keinen festen Platz in der Kette der PKI-Abläufe ein, sondern kann auf unterschiedliche Art durchgeführt werden, zentralisiert oder selbstbedient. Davon sind einige Details des Personalisierungsprozesses abhängig. Der zentralisierten Personalisierung kann eine Freischaltung (Ändern der Transport-PIN) und Initialisierung (Schreiben weiterer Benutzerdaten) der Karte durch den Benutzer folgen (vgl. TUDCard 3.2.2). In Falle einer selbstbedienten Personalisierung ist dagegen keine Transport-PIN nötig. Die üblichen Funktionen aus dieser Gruppe sind: • Transport-PIN ändern • PIN mit FBZ setzen • PUK mit FBZ setzen • Schlüsselpaar auf der Karte erzeugen • PKCS#10-Zertifikatsantrag erstellen • Schlüsselpaar auf die Karte schreiben • Zertifikat auf die Karte schreiben 3. Erneuern und Hinzufügen der Karteninhalte • Schlüssel und Zertifikate überschreiben Durch die Verwendung von Smartcards als Hardware-PSE werden die Gesamtkosten der PKI erheblich erhöht. Unter diesen Umständen ist es sehr wichtig, dass Smartcards lange verwendet werden. Die Lebensdauer von vielen Karteninhalten ist relativ kurz im Vergleich zur Lebensdauer der Chipkarte (Schlüssel können kompromittiert werden, Zertifikate sind nur begrenzt gültig). Aus diesem Grund ist es notwendig, die Karteninhalte zu erneuern, damit die Smartcard weiter benutzt werden kann. 5.2. FUNKTIONALE ANFORDERUNGEN 41 • Neue Schlüssel und Zertifikate auf die Karte bringen Es kann passieren, dass neue Smartcard-Anwendungen in der PKI erst nach dem Rollout implementiert werden. Zum Beispiel ist es geplant, die TUDCard für Verschlüsselung zu benutzen, also noch mit einem Schlüsselpaar/Zertifikat auszustatten. Im dem Fall ist es notwendig, nach der Kartenpersonalisierung neue Inhalte (selbstbedient) auf die Karte einzuspielen. 4. Benutzung der kryptographischen Funktionalität der Karte Zu dieser Gruppe gehören kryptographische Funktionen der Smartcard. Für eine PKI sind die folgenden besonders relevant: • Digitale Signatur erzeugen • Daten entschlüsseln Eine Schnittstelle zu kryptographischen Funktionen ist zum Beispiel notwendig, wenn die Smartcard als Issuer-Karte benutzt wird, also zum Ausstellen von Zertifikaten. In diesem Fall ist der private Schlüssel der CA auf der Karte gespeichert und wird zum Erstellen der digitalen Signatur für Benutzerzertifikate verwendet. Die kryptographischen Funktionen können auch im Rahmen der Kartenpersonalisierung zum Einsatz kommen, zum Beispiel ist für die Erzeugung eines PKCS#10Zertifikatsantrags eine digitale Signatur erforderlich. Außerdem kann eine Entschlüsselung von Daten notwendig sein, zum Beispiel des Zertifikats. Dadurch wird ein Proofof-Possession vollzogen, d.h. der PKI-Nutzer weist nach, dass der zugehörige private Schlüssel tatsächlich in seinem Besitz ist. Bei der Ausführung kryptographischer Operationen muss die Möglichkeit gegeben sein, Schlüssel und Verfahren auszuwählen, wenn es mehrere zur Verfügung stehen. 5. Passwort-Management • PIN nach der Verifikation ändern • PIN mit Hilfe der PUK entsperren und neu setzen 6. Löschen der Karte • Bestimmte Karteninhalte (Schlüssel, Zertifikate) löschen Es ist notwendig, die kryptographischen Schlüssel am Ende ihres Lebenszyklus auf der Karte zu vernichten. Abgelaufene Zertifikate müssen auch gelöscht werden. • Karte inklusive PIN und PUK vollständig löschen Wenn ein Benutzer die PKI verlässt (ein Mitarbeiter verlässt das Unternehmen, ein Student wird exmatrikuliert, etc.), gibt er seine Smartcard zurück. In dem 42 KAPITEL 5. ANFORDERUNGSANALYSE Fall muss die Karte vollständig gelöscht werden, damit sie wieder neu personalisiert werden kann. Vollständiges Löschen ist auch als eine selbstbediente Operation denkbar, bevor der Benutzer seine Karte neu personalisiert. Zugriffe auf private Informationen auf der Smartcard, also Operationen der Gruppen 2 bis 6, dürfen erst nach einer Benutzer-Authentifikation stattfinden. Dafür müssen die Funktionen PIN verifizieren“ und PUK verifizieren“ eingesetzt werden. ” ” 5.3 Qualitätsanforderungen Es soll ein Framework entwickelt werden, also eine Anwendungsarchitektur vorgegeben werden. Dabei findet eine Umkehrung der Kontrolle statt: Der Anwendungsentwickler liefert konkrete Implementierungen, die dann durch das Framework gesteuert und benutzt werden, statt - wie bei einer Klassenbibliothek - lediglich Klassen und Funktionen zu benutzen. Ein Framework definiert insbesondere den Kontrollfluss der Anwendung und die Schnittstellen für die konkreten Klassen, die vom Anwendungsentwickler erstellt werden müssen. Das Framework soll die typischen Prozesse der Anwendungsdomäne auf einem hohen Abstraktionsniveau unterstützen. Insbesondere bedeutet dies, dass die Software von den Smartcard-Typen und standardisierten Smartcard-Schnittstellen abstrahieren soll. Dieses Vorgehen hat mehrere Vorteile: • Benutzerfreundlichkeit Anwendungsprogrammierer, die lediglich fertige Implementierungen benutzen wollen, müssen keine Details von Smartcard-Betriebssystemen und -Schnittstellen verstehen. • Transparenz Wenn ein COS-Update stattfindet oder ein neues Betriebssystem auf den Markt kommt, müssen neue Implementierungen für die definierten Schnittstellen geliefert werden. Für die Anwendung bleiben diese Änderungen jedoch transparent. Das gleiche gilt für neue Smartcard-Schnittstellen. Außerdem soll die Software flexibel und erweiterbar sein. Dies bezieht sich insbesondere auf: • Hinzunahme neuer Funktionalität • Hinzunahme neuer Smartcards • Hinzunahme neuer Smartcard-Schnittstellen 5.3. QUALITÄTSANFORDERUNGEN 43 Das Framework soll auch konfigurierbar sein, d.h. zentrale Komponenten sollen in unterschiedlichen Ausprägungen hinzugefügt werden können. Auf diese Weise kann die Funktionalität durch einfaches Ändern von Konfigurationsdateien ersetzt oder erweitert werden. 44 KAPITEL 5. ANFORDERUNGSANALYSE Kapitel 6 Design der Software Dieses Kapitel gibt einen Überblick über die entwickelte Software. Die grundlegenden Design-Entscheidungen werden beschrieben. Es werden Klassen und Methoden vorgestellt, die aus der Benutzersicht wichtig sind. Die Implementierungen des Frameworks werden im Kapitel 7 beschrieben. Dieses ist wichtig, wenn man die interne Struktur der Software verstehen will, um sie zu erweitern. Allgemeine Struktur Die entwickelte Software besteht aus folgenden Paketen: • de.tud.cdc.cardservices Der funktionale Kern des Frameworks. Der Kontrollfluss der Anwendung und die Schnittstellen für die konkreten Klassen sind hier definiert. Das Paket enthält auch Klassen zum Aufbau von APDUs und zum Austausch von APDUs mit der Smartcard. • de.tud.cdc.cardservices.pkcs11 Eine auf dem Java-PKCS#11-Provider [Vla00] basierte Implementierung für TCOS2.0Smartcards. • de.tud.cdc.cardservices.tcos20 Eine APDU-basierte Implementierung für TCOS2.0-Smartcards. • de.tud.cdc.cardservices.ocf Framework-Schnittstelle zu OCF. Unterstützt APDU-Austausch mit der Smartcard über den OCF-Wrapper für PC/SC. • de.tud.cdc.cardservices.pcsc Framework-Schnittstelle zu PC/SC. Unterstützt APDU-Austausch mit der Smartcard über JPC/SC. 45 46 KAPITEL 6. DESIGN DER SOFTWARE • de.tud.cdc.cardservices.examples Beispiele für die Verwendung der wichtigsten Framework-Funktionen. Die Kernklassen Es ist am einfachsten, die wichtigsten Klassen des Frameworks anhand eines Beispiels einzuführen. Eine Funktion, die in einem Smartcard-System sehr oft benötigt wird, ist das Auslesen der Seriennummern aller dem System zugänglichen Chipkarten. Um dies mit Hilfe des Frameworks und seiner PKCS#11-basierten Implementierung zu realisieren, muss das folgende Codestück geschrieben werden: Beispiel 6.0.1 (Ausgeben der Kartenseriennummern). String[] pkcs11Params = new String[]{"pkcs11.properties"}; ReaderDriver driver = new PKCS11ReaderDriver(pkcs11Params); CardManager cm = CardManager.getInstance(); cm.loadReaderDriver(driver); CardSlot[] cardSlots = cm.getSlotList(); for (int i = 0; i < cardSlots.length; i++) { Card smartcard = cardSlots[i].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); System.out.println("Card Serial Number: " + infoService.getSerialNumber());} Die wichtigsten Klassen und Interfaces des Frameworks sind in diesem Beispiel schon vertreten. Dazu gehören zum einen ReaderDriver und CardSlot, welche analog zu physikalischen Kartenlesertreibern und Terminals die Kommunikation mit der Smartcard vermitteln. Ein CardManager-Objekt übernimmt die Verwaltung von ReaderDrivers und CardSlots. Zum anderen gibt es eine Hierarchie von CardServices, welche verschiedene Dienste einer Smartcard repräsentieren, wie InfoCardService im obigen Beispiel. CardServices werden im Detail im Abschnitt 6.3 beschrieben. Die Klasse Card repräsentiert eine Smartcard und liefert für diese Smartcard verfügbare Dienste. 6.1 Verwaltung der Ressourcen Die Verwaltung der Chipkarten im System geschieht über die Klassen CardManager und ReaderDriver. 6.1. VERWALTUNG DER RESSOURCEN 6.1.1 47 CardManager Die zentrale Verwaltung der Kartenlesertreiber und verfügbarer Terminals übernimmt ein CardManager-Objekt. Daher muss CardManager immer als erstes instanziiert werden. Dies geschieht über die Methode CardManager.getInstance(), welche die einzig im System vorhandene Instanz von CardManager zurückliefert. Dazu wird das Singleton Design Pattern [Eri95] verwendet. Es stellt sicher, dass zu der Klasse CardManager nur genau ein Objekt erzeugt werden kann und ermöglicht einen globalen Zugriff auf dieses Objekt. Die Abbildung 6.1 gibt eine Übersicht über die Funktionen der Klasse CardManager. de.tud.cdc.cardservices.CardManager + getInstance(): CardManager + init(args: String): CardManager + getSlotList(): CardSlot[] + loadReaderDriver(driver: ReaderDriver) + unloadAllDrivers() Abbildung 6.1: Die Klasse CardManager mit ihren öffentlichen Funktionen. Nach der Instanziierung kann das CardManager-Objekt benutzt werden, um Kartenlesertreiber zu laden. Dies geschieht über die Funktion loadReaderDriver, die ein ReaderDriver-Objekt als Argument übernimmt. Die Methode getSlotList() liefert ein Array von verfügbaren CardSlots. Dies geschieht, indem der CardManager alle geladenen Treiber nach ihnen zugänglichen Slots abfragt und anschließend eine Gesamtliste zurückliefert. Um alle geladenen Kartenlesertreiber zu stoppen und auszuladen, verwendet man die Methode unloadAllDrivers(). Eine weitere Möglichkeit, das CardManager-Objekt zu instanziieren und gleichzeitig ReaderDrivers zu laden, bietet die Methode CardManager.init(String args). Dazu muss als Argument ein String übergeben werden, welcher aus Klassennamen von den zu ladenden ReaderDrivers und den Namen der zugehörigen Property-Files besteht (s. Abschnitt 6.1.2). Die Klassennamen von ReaderDrivers und ihre Parameter sind durch ein Leerzeichen, die Parameterlisten durch ein Semikolon zu trennen: Beispiel 6.1.1 (Verwendung von CardManager.init(String args)). CardManager cm = CardManager.init("de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties; 48 KAPITEL 6. DESIGN DER SOFTWARE de.tud.cdc.cardservices.pkcs11.PKCS11ReaderDriver pkcs11.properties"); Dieses Codestück instanziiert das CardManager-Objekt und lädt zwei ReaderDrivers, de.tud.cdc.cardservices.ocf.OCFReaderDriver mit den Property-Files opencard.properties und tcos20.properties und de.tud.cdc.cardservices.pkcs11.PKCS11ReaderDriver mit dem Property-File pkcs11.properties. 6.1.2 ReaderDriver ReaderDriver ist eine abstrakte Klasse, die einen Kartenlesertreiber repräsentiert. Über ein ReaderDriver-Objekt können die zugehörigen CardSlots angesprochen werden. Das UML-Klassendiagramm ist in der Abbildung 6.2 dargestellt. de.tud.cdc.cardservices.ReaderDriver + ReaderDriver(props: Properties) + ReaderDriver(filenames: String[]) + getProperties(): Properties + open() + is Active(): boolean + getSlotList(): CardSlot[] + getName(): String + close() Abbildung 6.2: Die Klasse ReaderDriver mit ihren öffentlichen Funktionen. Um einen ReaderDriver zu laden, sind im allgemeinen bestimmte Parameter notwendig, zum Beispiel der Name einer nativen Bibliothek. Diese können als Properties beim Erzeugen der ReaderDriver-Instanz übergeben werden. Außerdem können an dieser Stelle Properties übergeben werden, welche von den vom ReaderDriver erzeugten Objekten benötigt werden, zum Beispiel von CardSlots. Der zweite Klassenkonstruktor ReaderDriver(String[] filenames) erwartet als Argument-Array die Namen von Property-Files, aus welchen Properties für die neue Instanz zu laden sind. Die abstrakten Methoden der Klasse, die von den konkreten Unterklassen implementiert werden, sind die folgenden: • open() startet den zugehörigen Kartenlesertreiber. • isActive() gibt Auskunft darüber, ob der Treiber gestartet ist. 6.2. KOMMUNIKATION MIT DER SMARTCARD 49 • getSlotList() liefert ein Array von CardSlots zurück, die für diesen Treiber verfügbar sind. • getName() liefert eine textuelle Beschreibung von dem Treiber. • close() stoppt den Kartenlesertreiber. 6.2 6.2.1 Kommunikation mit der Smartcard CardSlot Im System können sich ein oder mehrere Kartenterminals jeglicher Art befinden. CardSlots sind eine Abstraktion dafür auf Java-Ebene. Die Methode getSlotList() von CardManager liefert eine Liste von verfügbaren Kartenterminals. Das Interface CardSlot ist in der Abbildung 6.3 dargestellt. «interface» de.tud.cdc.cardservices.CardSlot + hasCardInserted(): boolean + getCard(): Card + getID(): String + getManufacturerID(): String Abbildung 6.3: Das Interface CardSlot. Die Funktionen des Interfaces getID(), getManufacturerID() und hasCardInserted() liefern Informationen über das Kartenterminal. Ein Kartenterminal vermittelt die Kommunikation der Anwendung mit der Smartcard. Diese Semantik wurde beibehalten; demnach liefert die Methode getCard() ein CardObjekt zurück, welches die Smartcard repräsentiert. 6.2.2 Card Die abstrakte Klasse Card repräsentiert eine Smartcard und stellt die für diese Smartcard verfügbaren Dienste zur Verfügung. Die Smartcard-Dienste werden als CardServices bezeichnet und im Abschnitt 6.3 detailliert beschrieben. Die Abbildung 6.4 stellt das UMLDiagramm der Klasse Card dar. Ein Card-Objekt ist der Rückgabewert der Methode getCard() von CardSlot. Für jede Chipkarte im System kann maximal ein Card-Objekt existieren, welches die Übersicht über 50 KAPITEL 6. DESIGN DER SOFTWARE de.tud.cdc.cardservices.Card - instantiatedServices: Hashtable # Card(props: Properties) + getProperties(): Properties + getName(): String # getNativeObject(): Object + getCardService(serviceInterface: Class): CardService # getServiceClassName(serviceInterface: Class): String # instantiateCardService(cardServiceImpl: Class): CardService Abbildung 6.4: Die Klasse Card mit ihrer wichtigsten Funktionalität. die für diese Chipkarte verfügbare und instanziierte CardServices hat und auf Anfrage sie zurückliefert. Der Klassenkonstruktor übernimmt Properties als Argument. Auf diese Art kann eine CardService-Implementierung spezifiziert werden (s. unten). Außerdem können an dieser Stelle Properties für die von Card erzeugten CardServices übergeben werden. Die wichtigste Funktion eines Card-Objekts ist das Bereitstellen von CardServices. Dies geschieht über die Methode getCardService(Class serviceInterface), welche das gewünschte CardService-Interface als Argument erwartet und eine Implementierung dieses Interfaces zurückliefert (vgl. mit dem Beispiel 6.0.1). Dies läuft wie folgt ab: 1. Als erstes wird überprüft, dass serviceInterface ein CardService definiert, d.h. es muss das Interface CardService erweitern und selbst ein Interface sein. 2. Als nächstes muss entschieden werden, welche Implementierung von serviceInterface zurückgeliefert werden soll. Diese Entscheidung wird in der Methode getServiceClassName(Class serviceInterface) getroffen, welche den vollständigen Namen einer konkreten Implementierung von serviceInterface zurückgibt. Diese Methode ist als protected deklariert und kann von Card-Unterklassen überschrieben werden. Card stellt jedoch einen Default-Algorithmus zur Auswahl der CardService-Implementierung zur Verfügung: (a) Es wird überprüft, ob in den Properties eine Implementierung spezifiziert ist, zum Beispiel InfoCardService = com.myimpl.MyInfoService 6.2. KOMMUNIKATION MIT DER SMARTCARD 51 oder InfoCardService = MyInfoService Falls kein vollständiger Name, also nur der Klassenname angegeben ist, wird dem der Name des aktuellen Pakets vorangestellt. (b) Wenn in den Properties keine Implementierung spezifiziert ist, wird ein DefaultKlassenname gebildet. Dieser setzt sich aus dem Rückgabewert von getName() und dem serviceInterface-Klassennamen zusammen, wobei als Package-Name der Name vom aktuellen Paket benutzt wird: String subclassSimpleName = this.getName() + serviceInterface.getSimpleName(); String subclassFullName = this.getClass().getPackage().getName() + "." + subclassSimpleName; return subclassFullName; 3. Es wird überprüft, ob die gewünschte Implementierung vorhanden ist und ob sie serviceInterface tatsächlich implementiert. 4. Falls für diese Card die gewählte serviceInterface-Implementierung schon instanziiert wurde, wird die gespeicherte Instanz zurückgegeben. Ansonsten wird eine neue Instanz erzeugt. Dazu wird die abstrakte Methode instantiateCardService(Class cardServiceImpl) aufgerufen. Die Methode wird von Card-Unterklassen implementiert; dort wird auch entschieden, welche Parameter an den Konstruktor von cardServiceImpl übergeben werden müssen. Das neue CardService-Objekt wird zurückgeliefert und für zukünftige Anfragen gespeichert. Die Instanziierung von CardServices auf diese Art trägt der Flexibilität, Erweiterbarkeit und Übersichtlichkeit der Software bei. Alternativ hätte man für jeden CardService eine Methode in der Klasse Card vorsehen können, wie getInfoCardService(), getSignatureCardService() usw. So würde jedoch das System an Erweiterbarkeit verlieren, denn für jeden neuen CardService eine Methode in die Klasse Card hinzugefügt werden müsste. Außerdem würden die vielen Methoden die Klasse unnötig überladen. Wenn man nun eine Methode für alle CardServices hat, muss das gewünschte Interface als Parameter übergeben werden. Dadurch, dass es als Class zu übergeben wird (und nicht zum Beispiel als String), wird sicher gestellt, dass dieses Interface spätestens zur Laufzeit des Programms im System existiert. Außerdem wird dadurch die Flexibilität erhöht, denn so können CardServices dynamisch geladen werden. Diese Vorteile lassen es leicht in Kauf nehmen, dass die Methode ein generisches CardService-Objekt zurückliefert, welches wie im Beispiel 6.0.1 in den richtigen Typ umgewandelt werden muss. Die Tatsache, dass es für eine Card maximal ein Objekt von jedem CardService-Typ existieren kann, wird dadurch erklärt, dass CardServices interne Zustandsinformationen 52 KAPITEL 6. DESIGN DER SOFTWARE speichern können. Wenn es mehrere CardServices vom gleichen Typ gäbe, könnten ihre Zustände inkonsistent zueinander werden. Es sei auch bemerkt, dass die Methode getCardService eine Kombination von Design Patterns Factory Method und Template Method (s. [Eri95]) realisiert, was die Flexibilität und Erweiterbarkeit der Software erhöht: Template Method : Die für alle Unterklassen gemeinsame Funktionalität ist in der öffentlichen Methode getCardService gespeichert und ihre spezifischen Anteile sind in die Methoden getServiceClassName und instantiateCardService ausgelagert. Dabei muss die Methode instantiateCardService zwangsläufig von allen konkreten Unterklassen implementiert werden, während getServiceClassName eine DefaultImplementierung bereitstellt. Dieses Design Pattern ermöglicht, einzelne Schritte des Algorithmus zu modifizieren oder zu überschreiben, ohne dass die grundlegende Struktur des Algorithmus verändert wird. Factory Method : Die Methode getCardService liefert lediglich ein Interface zurück, dessen konkrete Implementierung von den Unterklassen ausgewählt werden kann. Dazu muss die Methode getServiceClassName überschrieben werden. Durch die Verwendung dieses Design Patterns werden die Aufrufer von der Methode getCardService von Implementierungen konkreter CardService-Klassen entkoppelt. Der Konstruktor und Funktionen getServiceClassName und instantiateCardService sind als protected deklariert und damit außerhalb des Pakets nur für Unterklassen zugänglich. Dies ist eine Information-Hiding-Maßnahme. Diese Eigenschaft ist wünschenswert, denn eine Applikation nie direkt eine Card erzeugen muss, sondern bekommt ein Objekt über die Methode getCard() von Slot. Die Methode getName() liefert eine kurze textuelle Bezeichnung für diese Card, welche keine Leerzeichen enthalten sollte, damit die Default-Implementierung der Methode getServiceClassName fehlerfrei funktioniert (s. 2b). Die Funktion getNativeObject() gibt das native Objekt von dieser Card zurück. Der Rückgabetyp ist a priori unbekannt, deswegen wird ein Object zurück geliefert, welches im Kontext in den richtigen Typ umgewandelt werden muss. Diese Methode ist als protected deklariert, damit außerhalb des Pakets nur die Unterklassen Zugriff auf das native Objekt haben. 6.3 CardServices Smartcard-Servicefunktionen werden vom Framework in Form von Smartcard-Diensten zur Verfügung gestellt. Diese Dienste werden als CardServices bezeichnet. Die Imple- 6.3. CARDSERVICES 53 mentierung eines CardService ist für die Anwendung transparent und kann jeder Zeit ausgetauscht werden. Ein CardService stellt eine Menge von Smartcard-Servicefunktionen dar, die einem gemeinsamen oder ähnlichen Zwecken dienen. In der Regel entspricht ein CardService einem Smartcard-Anwendungsfall und umfasst die Funktionen, die für diesen Anwendungsfall benötigt werden. Die typischen Smartcard-Anwendungsfälle im Rahmen einer Sicherheitsinfrastruktur wurden im Abschnitt 5.2 beschrieben. Wir führen sie nochmal auf: • Auslesen öffentlicher Informationen von der Karte • Personalisierung der Karte • Erneuern und Hinzufügen der Karteninhalte • Benutzung der kryptographischen Funktionalität der Karte • Passwort-Management • Löschen der Karte Ausgehend von diesen Anwendungsfällen wurde eine Hierarchie von CardServices entwickelt. Ein CardService entspricht meist einem deiser Anwendungsfälle, es haben sich allerdings ein paar Schnittstellenmodifizierungen ergeben, um die Implementierung zu vereinfachen. Es wäre auch möglich, alle Smartcard-Funktionen in einem Interface zu definieren und später in einer Klasse zu implementieren. Die Entscheidung für CardServices bietet jedoch im Vergleich dazu mehrere Vorteile: • Kompakte, anwendungsfallorientierte Interfaces und Klassen vereinfachen die Darstellung und das Verständnis der Software. • Durch die Aufteilung der Funktionalität in kleine Einheiten wird die Software-Pflege einfacher. Dies sind die typischen Vorteile des Grundsatzes Teile und herrsche (lat. divide et impera). • Erweiterbarkeit Würde man alle Funktionen in einer Klasse realisieren, so müsste diese Klasse jedes Mal modifiziert werden, wenn die Software um neue Funktionen erweitert werden soll. Die CardServices-Lösung ermöglicht Software-Erweiterung ohne Codemodifikation — es genügt, einen neuen CardService zu definieren und zu implementieren oder einen bestehenden CardService zu erweitern. Die Framework-Klassen arbeiten mit generischen CardService-Objekten, so dass der konkrete Objekt-Typ keine Rolle spielt. 54 KAPITEL 6. DESIGN DER SOFTWARE • Flexibilität Für einen CardService können viele Implementierungen existieren. Durch Properties von Card (zum Beispiel in einer Konfigurationsdatei festgelegt) kann die gewünschte Implementierung angegeben werden (s. Abschnitt 6.2.2). Mit den im folgenden vorgestellten CardServices wurde es versucht, den wichtigsten funktionalen Anforderungen von Smartcard-Sicherheitsinfrastrukturen gerecht zu werden. In den meisten Systemen werden jedoch auch spezifische Smartcard-Funktionen benötigt, die auf einem hohen Abstraktionsniveau nicht vorgesehen werden können. Daher wurde eine aufwandsminimierte Erweiterung als ein wichtiges Designziel angestrebt. Das UML-Klassendiagramm von der CardService-Hierarchie ist in der Abbildung 6.5 dargestellt. 6.3.1 CardService CardService ist das Oberinterface für alle Smartcard-Dienste und muss von allen CardServices erweitert werden. Es wurde aussließlich für Erweiterung konzipiert und als abstract interface deklariert, um zu kennzeichnen, dass eine konkrete Implementierung nicht erlaubt ist. Das Interface ist in der Abbildung 6.5 zu finden und definiert die folgenden Methoden: • getName() liefert eine kurze textuelle Beschreibung eines CardService • getCard() gibt das zugehörige Card-Objekt zurück. Diese Methode ist auch intern wichtig, wenn CardServices sich gegenseitig benutzen sollen. In dem Fall kann ein CardService bei seiner Card einen anderen CardService bestellen“. ” • CardServices können mit bestimmten Konfigurationsparametern initialisiert werden, welche als Properties übergeben werden sollen. Die Methode getProperties() liefert diese zurück. 6.3.2 InfoCardService InfoCardService basiert auf dem Anwendungsfall Auslesen öffentlicher Informationen ” von der Karte“ (s. Abschnitt 5.2). Dabei handelt es sich um einen öffentlichen SmartcardDienst, d.h. es muss keine PIN-Verifikation stattfinden, um diesen CardService zu benutzen. InfoCardService ist der Abbildung 6.5 dargestellt. Die meisten Funktionen des Interfaces sind selbsterklärend. Sie können in drei Gruppen unterteilt werden: • Statische Karteninformationen und Kartenstatus getLabel, getSerialNumber, isPersonalized. 6.3. CARDSERVICES 55 «interface» de.tud.cdc.cardservices.CardService + getName(): String + getCard(): Card + getProperties(): Properties «interface» de.tud.cdc.cardservices.PasswordCardService + initializePUK(puk: byte[]) + initializePIN(puk: byte[], pin: byte[]) + verifyPIN(pin: byte[]) + verifyPUK(puk: byte[]) + changePIN(oldPin: byte[], newPin: byte[]) + unblockPIN(puk: byte[], newPin: byte[]) «interface» de.tud.cdc.cardservices.InfoCardService + getLabel(): String + getSerialNumber(): String + getPublicKeys(): java.security.PublicKey[] + getX509Certificates(): java.security.cert.X509Certificate[] + getPrivateKeyRefs(): CardObjectRef[] + getPublicKeyRefs(): CardObjectRef[] + getX509CertificateRefs(): CardObjectRef[] + getDataObjectRefs(): CardObjectRef[] + isPersonalized(): boolean + isPINInitialized(): boolean + isPUKInitialized(): boolean + isPINCountLow(): boolean + isPUKCountLow(): boolean + isPINLocked(): boolean + isPUKLocked(): boolean «interface» de.tud.cdc.cardservices.LoginCardService + login(pin: byte[]) «interface» de.tud.cdc.cardservices.InitCardService + createPUK(puk: byte[]) + createPIN(puk: byte[], pin: byte[]) + changeTransportPIN(newPin: byte[]) + generateKeyPair(keyLength: int) + createPEMCertificateRequest(forPubK: java.security.PublicKey, privK: CardObjectRef, signatureAlg: String, name: codec.x501.Name): codec.pkcs10.CertificationRequest + writeKeyPair(pubK: java.security.PublicKey, privK: java.security.PrivateKey) + writeKeyPair(pubK: java.security.PublicKey, privK: java.security.PrivateKey, privKeyId: CardObjectID) + writeKeyPairAndX509Certificate(pubK: java.security.PublicKey, privK: java.security.PrivateKey, cert: java.security.cert.X509Certificate) + writeKeyPairAndX509Certificate(pubK: java.security.PublicKey, privK: java.security.PrivateKey, cert: java.security.cert.X509Certificate, privKeyId: CardObjectID) + writeX509Certificate(cert: java.security.cert.X509Certificate) + writeData(data: byte[], dataId: CardObjectID) «interface» de.tud.cdc.cardservices.DeleteCardService + deleteKeyPair(privKeyId: CardObjectID) + deleteX509Certificate(certId: CardObjectID) + deleteKeyPairAndX509Certificate(privKeyId: CardObjectID) + deleteDataObject(dataId: CardObjectID) + deleteAllX509Certificates() + deleteAllKeyPairs() + deleteAllDataObjects() + deleteAllCardObjects() + deleteCard(puk: byte[]) «interface» de.tud.cdc.cardservices.SignatureCardService + sign(privKeyRef: CardObjectRef, signatureAlg: String, data: byte[]): byte[] «interface» de.tud.cdc.cardservices.CASignatureCardService + sign(singatureAlg: String, data: byte[]): byte[] Abbildung 6.5: Die Klassenhierarchie von CardServices. 56 KAPITEL 6. DESIGN DER SOFTWARE • PIN- und PUK-Status isPINInitialiazed, isPUKInitialized, isPINcountLow, isPUKCountLow, isPINLocked, isPUKLocked. • Öffentliche Schlüssel und Zertifikate getPublicKeys, getX509Certificates. • Referenzen auf Objekte auf der Karte getPublicKeyRefs, getPrivateKeyRefs, getX509CertificateRefs, getDataObjectRefs. Der Rückgabetyp dieser Methoden ist ein Array von CardObjectRef. Wie der Name schon sagt, dient diese Klasse dazu, Objekte auf der Smartcard zu referenzieren. Sie wird im Abschnitt 6.4.2 detailliert erklärt. Die Methode getDataObjectsRefs liefert Referenzen auf alle Datenobjekte auf der Karte zurück. Im Allgemeinen kann ein Datenobjekt beliebige Benutzerdaten beinhalten, die keine kryptographischen Objekte sind. Auf der TUDCard wird zum Beispiel eine Kopie der PUK gespeichert (s. Abschnitt 3.2.2). Ein weiteres Beispiel ist ein digitales Foto des Karteninhabers. Ein erstes Beispiel der Benutzung von InfoCardService wurde schon gegeben (Beispiel 6.0.1). Im folgenden wird gezeigt, wie alle Zertifikate von der Karte ausgelesen und ihre Subject Distiquished Names ausgegeben werden können. Dabei wird die Implementierung des Frameworks für die TCOS2.0-Smartcard und die Frameworkschnittstelle zu PC/SC verwendet. Beispiel 6.3.1 (Ausgeben der X.509-Zertifikate). CardManager cm = CardManager.init( "de.tud.cdc.cardservices.pcsc.PCSCReaderDriver tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); for (int i = 0; i < cardSlots.length; i++) { Card smartcard = cardSlots[i].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); X509Certificate[] certs = infoS.getX509Certificates(); System.out.println("certificates found : " + certs.length); for(int j = 0; j < certs.length; j++){ System.out.println("Certificate Subject DN: " + certs[j].getSubjectDN().getName()); 6.3.3 }} PasswordCardService Dieser CardService umfasst alle Passwort-Funktionen der Smartcard. Es wurde von dem Regelfall ausgegangen, in dem eine Chipkarte zwei Passwörter hat, die PIN und die 6.3. CARDSERVICES 57 PUK. Wie dem UML-Diagramm in der Abbildung 6.5 zu entnehmen ist, gehören zu PasswordCardService die folgenden Methoden-Gruppen: • Anlegen von Passwörtern initializePIN, initializePUK. • Passwortverifikation verifyPIN, verifyPUK. • Passwort-Management changePIN, unblockPIN. Es ist eine Designentscheidung gewesen, diesem Dienst alle Passwort-Funktionen zuzuordnen, und nicht nur die Funktionen zum Passwort-Management (vgl. mit dem Abschnitt 5.2). Die Sicherheit der Smartcard-Benutzung beruht auf der Kenntnis der PIN und der PUK. Wer die Passwörter kennt und die Chipkarte in seinem Besitz hat, hat den Zugang zu allen Informationen auf der Karte. Die Übertragung der Passwörter zur Smartcard ist deswegen höchst sicherheitskritisch. Wenn sie in eine Klasse ausgelagert ist, ist es einfacher, die nötige Sicherheit zu gewährleisten. Implementierungen von PasswordCardService können zum Beispiel Secure-Messaging unterschtützen. Die Passwort-Funktionen, insbesondere die Verifikation der PIN, werden von den meisten Smartcard-Diensten benötigt. Ist dies der Fall, so soll der CardService die benötigten Funktionen nicht selbst implementieren, sondern sich der Funktionalität eines PasswordCardService bedienen. Dies gilt insbesondere für den LoginCardService. Beispiel 6.3.2 (Entsperren der PIN). CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); for (int i = 0; i < cardSlots.length; i++) { Card smartcard = cardSlots[i].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); if(infoService.isPINLocked()){ PasswordCardService passwordService = (PasswordCardService)smartcard.getCardService(PasswordCardService.class); passwordService.unblockPIN("004711".getBytes(), "000815".getBytes()); //PUK ist 004711, PIN wird auf 000815 gesetzt }} 58 KAPITEL 6. DESIGN DER SOFTWARE 6.3.4 LoginCardService Auf die geheimen Informationen in der Smartcard darf erst nach einer erfolgreichen Benutzerauthentifikation zugegriffen werden. Wenn ein CardService mit geheimen Informationen arbeitet, muss er eine Methode zur PIN-Verifikation anbieten. Durch eine erfolgreiche Verifikation der PIN loggt sich der legitime Benutzer auf die Karte ein. LoginCardService ist das Oberinterface für alle Smartcard-Dienste, die das Einloggen des Benutzers unterstützen. Es besteht nur aus der Methode login, welche die PIN als Argument übernimmt. 6.3.5 InitCardService InitCardService wurde ausgehend vom Anwendungsfall Personalisierung der Karte“ (s. ” Abschnitt 5.2) entwickelt. Bei diesem Anwendungsfall geht es darum, Benutzerdaten auf die Karte zu bringen. Das gleiche wird jedoch auch im Anwendungsfall Erneuern und ” Hinzufügen der Karteninhalte“ gemacht. Die beiden Anwendungsfälle sind insbesondere aus der Implementierungssicht sehr ähnlich — es geht darum, Informationen auf die Karte zu schreiben oder zu überschreiben. Aus diesem Grund wurde entschieden, Funktionen zum Einspielen neuer Karteninhalte in einem CardService zu definieren. InitCardService ist in der Abbildung 6.5 dargestellt und umfasst die folgenden Funktionsgruppen: • Initialisierung der Kartenpasswörter createPUK, createPIN, changeTransportPIN. • Schlüsselerzeugung auf der Karte generateKeyPair, createPEMCertificateRequest. Die Methode generateKeyPair erzeugt in der Smartcard ein Schlüsselpaar mit der als Parameter angegebener Länge. Die Funktion createPEMCertificateRequest liefert ein PKCS#10-Zertifikatsantrag für den als Argument übergebenen PublicKey zurück, wozu dieser mit dem zugehörigen privaten Schlüssel signiert wird. Eine Referenz auf den privaten Schlüssel (ein CardObjectRef-Objekt) wird als Argument der Methode übergeben. • Schlüssel und Zertifikate auf die Karte schreiben writeKeyPair(pubK:PublicKey, privKey:PrivateKey), writeKeyPairAndX509Certificate(pubK:PublicKey, privKey:PrivateKey, cert:X509Certificate). Die Methode writeKeyPair schreibt ein Schlüsselpaar auf die Karte; writeKeyPairAndX509Certificate spielt ein Schlüsselpaar und das zugehörige Zertifikat ein. 6.3. CARDSERVICES 59 Bei dieser Methodengruppe werden Daten auf die Karte geschrieben, und nicht über schrieben. D.h. die Datenkennungen werden automatisch vom InitCardService generiert. Die ggf. vorhandenen Karteninhalte werden durch den Aufruf einer dieser Methoden nicht betroffen und bleiben weiterhin in der Smartcard. • Schlüssel, Zertifikate und Datenobjekte (über)schreiben writeKeyPair(pubK:PublicKey, privKey:PrivateKey, privKeyId:CardObjectID), writeKeyPairAndX509Certificate(pubK:PublicKey, privKey:PrivateKey, cert:X509Certificate, privKeyId:CardObjectID), writeX509Certificate(cert:X509Certificate), writeData(data:byte[], dataObjId:CardObjectID). Die Methoden writeKeyPair und writeKeyPairAndX509Certificate verlangen im Vergleich zur vorherigen Methodengruppe einen zusätzlichen Parameter privKeyId vom Typ CardObjectID. Ein CardObjectID dient dazu, ein Objekt auf der Karte eindeutig zu identifizieren (s. Abschnitt 6.4.1). Den Parameter privKeyId kann man mit der Pfadangabe beim Erzeugen einer Datei in gewöhnlichen Betriebssystemen vergleichen. privKeyId gibt an, unter welcher Kennung der private Schlüssel auf der Karte zu speichern ist. Die Kennungen des öffentlichen Schlüssels und des Zertifikats hängen mit der Kennung des privaten Schlüssels zusammen und werden intern daraus berechnet. Ist ein privater Schlüssel mit der angegeben privKeyId auf der Karte schon vorhanden, so wird dieser überschrieben. Das gleiche gilt für den öffentlichen Schlüssel und für das Zertifikat. Die Funktion writeX509Certificate spielt ein Zertifikat auf die Karte ein, unter der Bedingung, dass der zugehörige öffentliche Schlüssel auf der Karte vorhanden ist. Wenn ein Zertifikat für diesen Schlüssel auf der Karte gespeichert ist, wird es überschrieben. Die Methode writeData(data:byte[], dataObjId:CardObjectID) speichert die als Byte-Array übergebenen Daten unter der angegebenen Kennung auf der Karte ab. Wenn ein Datenobjekt mit der Kennung dataObjId auf der Karte schon vorhanden ist, wird es dabei überschrieben. Die oben beschriebene Semantik der Funktionen kann nicht durch das Interface festgelegt werden. Es definiert ja nur die Methodensignaturen. Konkrete Implementierungen sollen trotzdem diese Semantik beibehalten, damit keine Inkonsistenzen entstehen. Im Beispiel 6.3.3 wird gezeigt, wie ein Schlüsselpaar mit dem zugehörigen Zertifikat auf der Karte überschrieben werden kann. Dabei wird davon ausgegangen, dass zumindestens ein Schlüsselpaar auf der Karte vorhanden ist. Beispiel 6.3.3 (Überschreiben eines Schlüsselpaares und des zugehörigen Zertifikats). 60 KAPITEL 6. DESIGN DER SOFTWARE java.security.interfaces.RSAPrivateKey privateKey = ...; java.security.interfaces.RSAPublicKey publicKey = ...; java.security.cert.X509Certificate cert = ...; CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); CardObjectRef[] privateKeyRefs = infoService.getPrivateKeyRefs(); CardObjectID privateKeyId0 = privateKeyRefs[0].getCardObjectID(); //Schlüsselpaar Nr.0 wird überschrieben InitCardService initService = (InitCardService)smartcard.getCardService(InitCardService.class); initService.login("000815".getBytes()); //PIN ist 000815 initService.writeKeyPairAndX509Certificate(privateKey, publicKey, cert, privateKeyId0); 6.3.6 DeleteCardService Dieser CardService entspricht dem Anwendungsfall Löschen der Karte“ (s. Abschnitt ” 5.2). Wie dem UML-Klassendiagramm in der Abbildung 6.5 zu entnehmen ist, legt das Interface DeleteCardService die folgenden Methodengruppen fest: • Löschen bestimmter Karteninhalte deleteKeyPair, deleteKeyPairAndX509Certificate, deleteX509Certificate, deleteDataObject. Diese Funktionen übernehmen als Parameter ein CardObjectID. Wenn ein Schlüsselpaar gelöscht werden muss, ist es die Kennung des privaten Schlüssels. Die Kennungen des öffentlichen Schlüssels und ggf. des Zertifikats werden wie bei den writeMethoden des InitCardService daraus berechnet. Falls nur ein Zertifikat gelöscht werden muss, wird seine Kennung als Argument der Funktion deleteX509Certificate übergeben. • Löschen von Karteninhalten eines bestimmten Typs deleteAllKeyPairs, deleteAllX509Certificates, deleteAllDataObjects. • Löschen der Karte deleteAllCardObjects, deleteCard. 6.3. CARDSERVICES 61 Die Methode deleteAllCardObjects löscht alle Benutzerdaten auf der Karte bis auf PIN und PUK. D.h. alle Schlüsselpaare, Zertifikate und ggf. andere Daten werden gelöscht. Die Methode deleteCard löscht alle Daten auf der Karte, inklusive PIN und PUK. Als Parameter wird die PUK der Karte erwartet. Beispiel 6.3.4 (Löschen aller Schlüsselpaare und Zertifikate). CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); DeleteCardService deleteService = (DeleteCardService)smartcard.getCardService(DeleteCardService.class); deleteService.login("000815".getBytes()); //PIN ist 000815 deleteService.deleteAllKeyPairs(); deleteService.deleteAllX509Certificates(); 6.3.7 SignatureCardService Eine der wichtigsten Smartcard-Anwendungen ist die Erzeugung der digitalen Signatur. SignatureCardService ist eine einfache Abstraktion für diesen Anwendungsfall. Es definiert nur eine Methode sign, welche die Referenz auf einen auf der Karte gespeicherten privaten Schlüssel, den Signaturalgorithmus und die zu signierenden Daten als Parameter übernimmt. Beispiel 6.3.5 (Erzeugen der digitalen Signatur bei mehreren Schlüsselpaaren auf der Karte). byte[] toSign = ...; CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); CardObjectRef[] privateKeyRefs = infoService.getPrivateKeyRefs(); CardObjectID privateKeyId1 = privateKeyRefs[1].getCardObjectID(); //es wird mit dem privaten Schlüssel Nr.1 signiert SignatureCardService signService = (SignatureCardService)smartcard.getCardService(SignatureCardService.class); signService.login("000815".getBytes()); //PIN ist 000815 62 KAPITEL 6. DESIGN DER SOFTWARE signService.sign(privateKeyId1, "SHA1withRSA", toSign); SignatureCardService muss von anderen CardServices verwendet werden, wenn eine Signatur erzeugt werden soll, zum Beispiel vom InitCardService beim Erstellen eines PKCS#10-Zertifikatsantrags. 6.3.8 CASignatureCardService CASignatureCardService soll zur Erzeugung digitaler Signaturen verwendet werden, wenn es sich um eine Aussteller-Smartcard handelt. D.h. auf der Smartcard ist der private Schlüssel der CA gespeichert, welcher dazu benutzt wird, Zertifikate auszustellen. Das UML-Klassendiagramm ist in der Abbildung 6.5 zu finden. Das Interface CASignatureCardService definiert wie SignatureCardService eine Methode zur Erzeugung der digitalen Signatur, die jedoch weniger Parameter erwartet als sign von SignatureCardService. Da auf einer Aussteller-Smartcard sich nur ein Schlüsselpaar befindet, muss keine Referenz auf den privaten Schlüssel übergeben werden. Beispiel 6.3.6 (Erzeugen der digitalen Signatur des Ausstellers). byte[] toSign = ...; CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.PKCS11ReaderDriver pkcs11.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); CASignatureCardService caSignService = (CASignatureCardService)smartcard.getCardService(CASignatureCardService.class); caSignService.login("000815".getBytes()); //PIN ist 000815 caSignService.sign("MD5withRSA", toSign); //es wird mit dem privaten Schlüssel Nr.0 signiert 6.4 Referenzierung der Daten auf der Smartcard Objekte auf der Smartcard (Schlüssel, Zertifikate etc.) müssen von der Applikation referenziert werden können. Sind zum Beispiel mehrere Schlüsselpaare auf der Karte gespeichert, so muss man bei der Erzeugung einer Signatur angeben, mit welchem Schlüssel signiert werden soll. Das gleiche gilt für das Löschen und Überschreiben der Karteninhalte. Die Referenzierung von Objekten auf Karte wird durch Klassen CardObjectID und CardObjectRef realisiert. 6.4.1 CardObjectID Bei jeder Framework-Implementierung besitzt ein Datenobjekt auf der Karte eine eindeutige Kennung. In verschiedenen Implementierungen können die Objektkennungen sich 6.4. REFERENZIERUNG DER DATEN AUF DER SMARTCARD 63 jedoch unterscheiden. Zum Beispiel können Kartenobjekte mit eindeutigen symbolischen Namen oder mit einem Pfad im Dateisystem der Smartcard identifiziert werden. Das Interface CardObjectID ist eine Abstraktion für Objektkennungen jeglicher Art. Es ist in der Abbildung 6.6 dargestellt und definiert die folgenden Methoden: • equals stellt fest, ob zwei Kennungen gleich sind. • toSting liefert eine menschenlesbare Darstellung der Kennung. «interface» de.tud.cdc.cardservices.CardObjectID + equals(anId: CardObjectID): boolean + toString(): String de.tud.cdc.cardservices.CardFileObjectID - path: opencard.opt.iso.fs.CardFilePath + CardFileObjectID(path: CardFilePath) + equals (anId: CardObjectID): boolean + getFilePath(): CardFilePath + isGlobal(): boolean + isLocal(): boolean + toString(): String Abbildung 6.6: Das CardFileObjectID. Interface CardObjectID und seine Implementierung Im Paket de.tud.cdc.cardservices wird auch eine Implementierung des Interfaces mitgeliefert, die Klasse CardFileID. Sie kann in allen Implementierungen des Frameworks benutzt werden, die wie gewöhnliche Betriebssysteme Objekte auf der Karte mit einem Pfad im Dateisystem kennzeichnen. Die Klasse hat zusätzlich die folgenden Funktionen: • getFilePath liefert den Pfad im Dateisystem zurück 64 KAPITEL 6. DESIGN DER SOFTWARE • isLocal gibt true zurück, falls es sich um ein Object in einem Applikationsverzeichnis handelt. • isGlobal gibt true zurück, falls das Object sich im Wurzelverzeichnis, dem Master File, befindet. Für die Darstellung eines Pfades im Dateisystem der Smartcard wurde die Klasse opencard.opt.iso.fs.CardFilePath verwendet. Sie wird im Archiv base-opt.jar mitgeliefert, welches von [ocf] runtergeladen werden kann. 6.4.2 CardObjectRef Die eigentliche Referenzierung von Objekten auf der Smartcard wird durch die Klasse CardObjectRef realisiert. Die Referenz auf ein Objekt speichert die Objektkennung (CardObjectID), den Objekttyp (Zertifikat, privater Schlüssel, öffentlicher Schlüssel etc.) und das referenzierte Objekt selbst, falls es öffentlich ist. de.tud.cdc.cardservices.CardObjectRef + CERT: String {final} + DATA: String {final} + PASSWORD: String {final} + PRIV_KEY: String {final} + PUB_KEY: String {final} + SECRET_KEY: String {final} - cardObject: Object - cardObjectId: CardObjectID - cardObejctType: String + CardObjectRef(id: CardObjectID, objType: String, cardObect: Object) + getCardObject(): Object + getCardObjectID(): CardObjectID + getCardObjectType(): String Abbildung 6.7: Die Klasse CardObjectRef. Die Klasse CardObjectRef ist in der Abbildung 6.7 dargestellt. Ihre Methoden sind weitgehend selbsterklärend. Sie definiert auch Konstanten für verschiedene Objekttypen, die bei der Instanziierung als Parameter übergeben werden sollen. 6.5. APDU-AUSTAUSCH MIT DER SMARTCARD 65 An dieser Stelle sei bemerkt, dass bei der Referenzierung eines Objekts die Geheimhaltung privater Informationen der Karte gewährleistet wird. D.h. es ist zum Beispiel unmöglich, private Schlüssel aus entsprechenden Referenzen auszulesen. Wenn man dies versucht, wird ein Exception geworfen. Bei den Referenzen auf öffentliche Kartenobjekte dagegen liefert die Methode getObject das entsprechende Objekt zurück, das in den richtigen Typ umgewandelt werden muss. Der Typ des Objekts kann mit der Methode getType abgefragt werden. CardObjectRefs sind schon aus den Beispielen 6.3.3 und 6.3.5 bekannt. Das nachfolgende Beispiel zeigt, wie ein öffentliches Objekt aus seiner Referenz ausgelesen werden kann. Beispiel 6.4.1 (Auslesen des öffentlichen Schlüssels aus einem CardObjectRef-Objekt). CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.PKCS11ReaderDriver pkcs11.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); InfoCardService infoService = (InfoCardService)smartcard.getCardService(InfoCardService.class); CardObjectRef[] publicKeyRefs = infoService.getPublicKeyRefs(); java.security.PublicKey publicKey0 = (java.security.PublicKey)publicKeyRefs[0].getCardObject(); //der öffentliche Schlüssel Nr.0 6.5 APDU-Austausch mit der Smartcard Um APDU-Level-Implementierungen des Frameworks zu unterstützen, bietet das Paket de.tud.cdc.cardservices Klassen und Interfaces für den Aufbau und Austausch von APDUs an. 6.5.1 CommandApdu und ResponseApdu Die Klasse ByteArray ermöglicht den Aufbau und die gewöhnlichen Operationen auf Arrays von Bytes. Von ihr werden die Klassen CommandApdu und ResponseApdu abgeleitet, die eine Implementierung von Command- und Response-APDU nach ISO/IEC 7816 liefern (s. Abschnitt 2.3.6). Die Funktionen dieser Klassen dem ISO/IEC-7816-Kenner bekannt und auch sonst selbsterklärend. Die Klasse CommandApdu stellt auch die static Methode decodeInstruction zur Verfügung, die zu einem Instruction-Byte eine textuelle Kommandobezeichnung nach ISO/IEC 7816 zurückliefert. Dies wird zum Beispiel in der Methode toString benutzt, um das Kommando in einer menschenlesbaren Form auszugeben. Die Funktion encodeCommand 66 KAPITEL 6. DESIGN DER SOFTWARE de.tud.cdc.cardservices.ByteArray - buffer: byte[] + splitByteArray(input: byte[], length: int): ByteArray[] + ByteArray() + ByteArray(buffer: byte[]) + ByteArray(buffer: byte[], start: int, length: int) + append(suffix: byte) + append(suffix: byte[]) + getByte(index: int): byte + getBytes(): byte[] + getBytes(index: int, length: int) + getLength(): int + prepend(perfix: byte) + prepend(prefix: byte[]) + setByte(index: int, value: byte) + setBytes(value: byte[]) + toString(): String de.tud.cdc.cardservices.CommandApdu de.tud.cdc.cardservices.ResponseApdu - INS_DECODER: Hashtable + decodeInstruction(ins: byte): String + encodeCommand(command: String): byte + CommandApdu(cla: byte, ins: byte, p1: byte, p2: byte) + CommandApdu(cla: byte, ins: byte, p1: byte, p2: byte, data: byte[]) + CommandApdu(cla: byte, ins: byte, p1: byte, p2: byte, data: byte[], le: int) + CommandApdu(cla: byte, ins: byte, p1: byte, p2: byte, le: int) + CommandApdu(command: byte[]) + CommandApdu(header: byte[], data: byte[]) + CommandApdu(header: byte[], data: byte[], le: int) + CommandApdu(header: byte[], le: int) + getCLA(): byte + getINS(): byte + getP1(): byte + getP2(): byte + getLc(): int + getLe(): int + getDataBytes(): byte[] + getHeaderBytes(): byte[] + setCLA(cla: byte) + setINS(ins: byte) + setP1(p1: byte) + setP2(p2: byte) + toString(): String + ResponseApdu(response: byte[]) + ResponseApdu(data: byte[], sw1: byte, sw2: byte) + ResponseApdu(data: byte[], sw: byte[]) + ResponseApdu(response: byte[], index: int, length: int) + isStatusOk(): boolean + getDataBytes(): byte[] + getDataLength(): int + getSW(): int + getSW1(): byte + getSW2(): byte + getSWBytes(): byte[] + getSWString(): String + toString():String Abbildung 6.8: Die Klassen ByteArray, CommandApdu und ResponseApdu mit ihrer öffentlichen Funktionalität. 6.5. APDU-AUSTAUSCH MIT DER SMARTCARD 67 führt die umgekehrte Operation aus — sie liefert das Instruction-Byte zu einem Kommandonamen. 6.5.2 ApduChannel Das Interface ApduChannel definiert einen Kommunikationskanal zur Smartcard. Es wird benutzt, um APDUs mit der Smartcard auszutauschen. Ein ApduChannel nimmt CommandAPDUs entgegen und liefert ResponseAPDUs zurück. «interface» de.tud.cdc.cardservices.ApduChannel + open() + close() + isOpen(): boolean + sendCommandApdu(apdu: CommandApdu): ResponseApdu + getNativeObject(): Object Abbildung 6.9: Das Interface ApduChannel. Das Interface ist in der Abbildung 6.9 dargestellt: • Es definiert Funktionen zum Öffnen und Schließen des Kanals (open und close). Mit der Methode isOpen kann der aktuelle Kanalzustand abgefragt werden. • Senden von Kommandos zur Smartcard wird durch die Methode sendCommandApdu realisiert, die eine ReponseApdu zurückgibt. • Konkrete Implementierungen basieren auf Smartcard-Schnittstellen, die den APDUAustausch mit der Karte unterstützen. getNativeObject liefert das darunterliegende native Objekt zurück. 6.5.3 ApduChannelCard Die Klasse ApduChannelCard erweitert die Klasse Card (s. Abschnitt 6.2.2) und ist eine Abstraktion für alle Smartcards, mit denen durch Senden von APDUs über einen ApduChannel kommuniziert wird. Daher ist sie als abstract deklariert. Der Klassenkonstruktor übernimmt zusätzlich zu Properties einen ApduChannel als Argument, der zur Kommunikation mit der Karte benutzt werden soll. Die Methode getChannel liefert den cardChannel zurück. ApduChannelCard implementiert die abstrakte Methode getNativeObject von Card, indem sie die Methode getNativeObject von 68 KAPITEL 6. DESIGN DER SOFTWARE de.tud.cdc.cardservices.Card - instantiatedServices: Hashtable # Card(props: Properties) + getProperties(): Properties + getName(): String # getNativeObject(): Object + getCardService(serviceInterface: Class): CardService # getServiceClassName(serviceInterface: Class): String # instantiateCardService(cardServiceImpl: Class): CardService de.tud.cdc.cardservices.ApduChannelCard - cardChannel: ApduChannel # ApduChannelCard(cardChannel: ApduChannel, props: Properties) # getApduChannel(): ApduChannel # getNativeObject(): Object {implements} # getSecurity(): Security Abbildung 6.10: Die Klasse ApduChannelCard. cardChannel aufruft. Die abstrakte Methode getSecurity liefert eine Default-Implementierung des Interfaces Security (mehr dazu im Abschnitt 6.5.4) für diese ApduChannelCard. Die Methoden sind als protected deklariert, damit außerhalb des Pakets nur die Unterklassen darauf zugreifen können. 6.5.4 Security Im Abschnitt 2.3.8 wurde Secure-Messaging erklärt. Das Interface Security definiert Funktionen zum Starten und Beenden einer Secure-Messaging-Session für einen CardService: • In der Methode establishSecureMessaging wird eine Secure-Messaging-Session für den angegebenen CardService aufgebaut. Der Parameter authKey ist der gemeinsame geheime Schlüssel, der zur wechselseitigen Authentifikation von Smartcard und Applikation benutzt wird (s. Abschnitt 8.7 in [CEN04]). authKeyId ist die Kennung dieses Schlüssels auf der Karte. Falls keine wechselseitige Authentifikation nötig ist, können diese Parameter null sein. 6.6. WEITERE KLASSEN 69 Beim Aufbau von Secure-Messaging soll der von dem CardService benutzte ApduChannel mit einem sicheren Kanal ersetzt werden. Ein sicherer Kanal verschlüsselt die Daten und/oder berechnet deren kryptographische Prüfsumme, bevor er die Daten über den darunterliegenden unsicheren ApduChannel verschickt. Um einen sicheren Kanal aufzubauen, wird ein Session-Key benötigt. Falls dieser im Rahmen der wechselseitigen Authentifikation ausgetauscht werden soll, wird die Methode establishSecureMessaging(CardService cardService, byte[] authKey, CardObjectID authKeyId) verwendet. Wenn man die Secure-Messaging-Schlüssel explizit angeben möchte, soll die zweite Methode establishSecureMessaging benutzt werden. • Methode endSecureMessaging beendet die geöffnete Secure-Messaging-Session des angegebenen CardService. Der sichere Kanal wird mit dem ursprünglichen unsicheren Kanal ersetzt. «interface» de.tud.cdc.cardservices.Security + establishSecureMessaging(forCardService: CardService, authKey: byte[], authKeyId: CardObejctID) + establichSecureMessaging(forCardService: CardService, authKey: byte[], auhtKeyId: CardObjectID, encKey: byte[], encKeyId: CardObjectID, macKey: byte[], macKeyId: CardObjectID ) + endSecureMessaging(forCardService: CardService) Abbildung 6.11: Das Interface Security. Aufbau und Benutzung von Secure-Messaging kostet Zeit und Ressourcen, die für kryptographische Berechnungen gebraucht werden. Es sollte daher nur für die Übertragung sensibler Daten eingesetzt werden. Es ist zum Beispiel sinnlos, ein Zertifikat verschlüsselt auf die Smartcard zu übertragen. Eine sehr häufige Lösung besteht darin, dass nur die Kartenpasswörter mit Secure-Messaging übertragen werden. Da Security den Aufbau von Secure-Messaging für einen bestimmten CardService gestattet, kann es gezielt nur für die Übertragung sensibler Daten eingesetzt werden. Wenn nur die Kartenpasswörter mit Secure-Messaging übertragen werden sollen, so wird es nur für einen PasswordCardService aufgebaut. 6.6 Weitere Klassen RSAPublicKey Die Klasse de.tud.cdc.cardservices.RSAPublicKey implementiert das Interface java.security.interfaces.RSAPublicKey und stellt einen Kontainer für die Komponenten eines öffentlichen RSA-Schlüssels dar. Die Klasse wird benutzt, um den öffentlichen 70 KAPITEL 6. DESIGN DER SOFTWARE Exponenten und den RSA-Modul zu speichern, nachdem sie von der Smartcard ausgelesen wurden. Der Klassenkonstruktor hat die Form +RSAPublicKey(modulus:BigInteger, exponent:BigInteger). Die Methode getEncoded liefert den Schlüssel in der X.509Kodierung zurück. Sie wird bei der Erstellung von PKCS#10-Zertifikatsanträgen benutzt, um den öffentlichen Schlüssel zum Signieren vorzubereiten. CardException Eine de.tud.cdc.cardservices.CardException wird geworfen, falls ein Fehler im Programm auftritt. Auch wenn es unmöglich ist, Fehlermeldungen aus dem native Code im Programm aufzufangen, werden sie in CardExceptions gekapselt und an die Anwendung weiter gegeben. Dabei wurde es versucht, den Text von allen CardExceptions als menschenlesbare Sätze zu gestalten. UnsupportedCardOperationException UnsupportedCardOperationException ist ein Sonderfall und eine Unterklasse von CardException. Sie wird geworfen, wenn eine im Framework definierte Operation nicht implementiert werden kann. Dies kann durch Hardware- oder Software-Einschränkungen bedingt sein. So wird zum Beispiel die Generierung von Schlüsseln auf der Smartcard nicht von allen Kartenherstellern unterstützt. In dem Fall kann die Methode generateKeyPair von InitCardService (im Hardware) nicht implementiert werden. Daher soll an dieser Stelle eine UnsupportedCardOperationException geworfen werden. In späteren Versionen könnte man es sich überlegen, durch spezialisierte Unterklassen von CardException eine semantische Trennung in Klassen von zusammenhängenden Fehlern anzustreben. Diese könnten dann von der Applikation feiner behandelt werden. ByteUtil In der Klasse ByteUtil sind statische Methoden konzentriert, welche Datentypen String und int in bytes und byte-Arrays und zurück umwandeln. Die Methoden zielen in erster Linie darauf ab, APDU-Level-Implementierungen des Frameworks zu unterstützen, wo die ganze Kommunikation mit der Smartcard über byte-Arrays geschieht. 6.7 Konfiguration der Komponenten Um die zentralen Komponenten des Frameworks in unterschiedlichen Ausprägungen erhalten zu können, können Konfigurationsparameter beim Initialisieren eines ReaderDrivers übergeben werden. Die Konfigurationsparameter werden dann vom ReaderDriver den 6.7. KONFIGURATION DER KOMPONENTEN 71 von ihm erzeugten CardSlots mitgeteilt. Ein CardSlot übergibt sie seinerseits an die zugehörige Card, so dass die Konfigurationsparameter auch für CardServices zugänglich sind. In der Konfiguration kann zum Beispiel festgelegt werden, welche native Bibliothek zu laden ist (s. Abschnitt 6.1.2) oder welche Implementierung eines CardService zu verwenden ist (s. Abschnitt 6.2.2 2a). Die Konfiguration kann als java.util.Properties oder in Konfigurationsdateien an den Klassenkonstruktor des ReaderDrivers übergeben werden (s. auch Abschnitt 6.1.2). Bei einer Konfigurationsdatei handelt es sich um einfache Textdateien, bei welchen in jeder Zeile ein Konfigurationspaar <name> = <value> zu finden ist. Die eigentlichen Konfigurationswerte (value) werden über zugehörige Namen (name) angesprochen. Der genaue Aufbau einer Konfigurationsdatei ist in der Java API Dokumentation von java.util.Properties, Methode load, beschrieben. Beispiele der Konfigurationsdateien werden in 7.1.4, 7.3.3, 7.2.3 und 7.4.6 gegeben. 72 KAPITEL 6. DESIGN DER SOFTWARE Kapitel 7 Implementierungen In diesem Kapitel werden konkrete Realisierungen der Software vorgestellt. Das Framework wurde orientiert an die Kriterien der Verbreitung für die TCOS2.0-Smartcard und die Schnittstellen PKCS#11, OCF und PC/SC implementiert. Es wird hauptsächlich auf diejenigen Aspekte eingegangen, die zum Verständnis der internen Software-Struktur wichtig sind. Die einzelnen Details vorzustellen würde den Rahmen dieser Arbeit sprengen. In diesem Kapitel wird daher nicht jede Klasse mit ihren Methoden aufgezählt - dies wurde in der Javadoc-Dokumentation getan. 7.1 PKCS#11-Implementierung Die PKCS#11-Implementierung des Frameworks basiert auf dem an der TU Darmstadt entwickelten Java-PKCS#11-Provider [Vla00]. Java-PKCS#11-Provider bietet eine objektorientierte Schnittstelle zu Funktionen einer nativen PKCS#11-Bibliothek. Obwohl der Provider und somit auch die PKCS#11-Implementierung des Frameworks von der nativen Bibliothek unabhängig sind, muss an dieser Stelle leider bemerkt werden, dass native PKCS#11-Bibliotheken verschiedener Anbieter sich in der Funktionalität unterscheiden können. Die vorgestellte Implementierung wurde mit der Bibliothek kpkcs11hash.dll“ ” der Firma Kobil getestet. PKCS#11 ist eine High-Level-Kartenschnittstelle, die vom Betriebssystem der Smartcard abstrahiert. Dies bedeutet, dass die entwickelte PKCS#11-Implementierung prinzipiell mit allen Smartcards und Kartenlesern funktionsfähig ist, für die es eine native PKCS#11-Bibliothek gibt. Bei der Entwicklung wurden allerdings für TCOS2.0 spezifische Eigenschaften berücksichtigt, zum Beispiel die unterstützten Schlüsseltypen. Daher können für andere Karten geringe Anpassungen notwendig sein. Die PKCS#11-Implementierung befindet sich im Paket de.tud.cdc.cardservices.pkcs11. Die meisten Klassen des Pakets implementieren die Schnittstellen des Frameworks oder erweitern abstrakte Klassen. 73 74 KAPITEL 7. IMPLEMENTIERUNGEN 7.1.1 PKCS11ReaderDriver, PKCS11CardSlot, PKCS11Card Diese Klassen realisieren die im Paket de.tud.cdc.cardservices festgelegte Funktionalität und kapseln wichtige Objekte des Java-PKCS#11-Providers. PKCS11ReaderDriver erweitert die Klasse de.tud.cdc.cardservices.ReaderDriver und kapselt ein cdc.pkcs11.Pkcs11-Objekt. Die Methode open initialisiert den PKCS#11Provider für eine als Properties übergebene native PKCS#11-Bibliothek. Die Funktion getSlotList liefert ein Array von PKCS11CardSlots zurück. PKCS11CardSlot implementiert das Interface de.tud.cdc.cardservices.CardSlot und kapselt ein cdc.pkcs11.Slot-Objekt. Die Methode getCard öffnet die Verbindung zur Smartcard liefert eine PKCS11Card zurück, die mit einem cdc.pkcs11.Session-Objekt initialisiert wird. Für ein PKCS11CardSlot existiert nur eine PKCS11Card, d.h. es wird nur eine Session mit der Karte geöffnet. PKCS11Card erweitert die Klasse Card und stellt PKCS11CardServices zur Verfügung. Die protected Methode getSession macht die darunterliegende Session für PKCS11CardServices dieser Karte zugänglich. In finalize wird die Session geschlossen. Die Methode getName liefert PKCS11“ zurück. Mit diesem String beginnen auch alle ” CardService-Klassennamen, damit die Methode getCardService korrekt funktioniert (s. Abschnitt 6.2.2 2b). 7.1.2 PKCS11CardServices Die CardService-Hierarchie ist im Paket de.tud.cdc.cardservices.pkcs11 vollständig implementiert. Die Klasse PKCS11CardService implementiert das Interface CardService und ist die Oberklasse für alle anderen PKCS11-CardServices. Alle PKCS11CardServices übernehmen bei der Instanziierung eine PKCS11Card als Argument und bekommen somit den Zugang zur darunterliegenden Session. Da PKCS#11 eine High-Level-Schnittstelle ist, konnten viele Funktionen in den Unterklassen von PKCS11CardService als einfache Aufrufe realisiert werden, zum Beispiel die Methode getLabel von PKCS11InfoCardService: public String getLabel() throws CardException { try {return p11Slot.getTokenInfo().getLabel();} catch (Pkcs11Exception e) {throw new CardException(e); }} Andererseits wurde man mit den Einschränkungen von PKCS#11 konfrontiert. Im allgemeinen unterstützt die Schnittstelle das Nullpin-Verfahren nicht, und daher kann die Methode InitCardService.changeTransportPIN von PKCS11InitCardService nicht realisiert werden. An dieser Stelle wird ein UnsupportedCardOperationException geworfen. 7.1. PKCS#11-IMPLEMENTIERUNG 75 Außerdem gibt es bei PKCS#11 keine PIN und keine PUK, sondern man unterscheidet zwischen Benutzerrollen User“ und Security Officer“, die jeweils ein Passwort zum ” ” Einloggen auf die Karte haben. Wenn der Security Officer“ eingeloggt ist, so kann das ” Passwort vom User“ neu gesetzt werden. Da dies im wesentlichen einer PIN-Entsperrung ” mit Hilfe der PUK entspricht, können die beiden Passwörter als PIN und PUK betrachtet werden, um diese Einschränkung umzugehen. So wurde PKCS11PasswordCardService realisiert. 7.1.3 PKCS11CardObjectID Die Klasse PKCS11CardObjectID implementiert das Interface CardObjectID und repräsentiert eine PKCS#11-Objektkennung. Bei PKCS#11 werden Objekte auf der Karte mit symbolischen Namen referenziert. So bedeutet zum Beispiel die Kennung TCOS1-00“ ” Objekt 00 auf der TCOS-Smartcard im Slot 1. Allerdings ist diese Kennung nicht eindeutig - mehrere zusammengehörige Objekte können eine identische Kennung haben, zum Beispiel ein Schlüsselpaar und das zugehörige Zertifikat. Um Objektkennungen eindeutig zu halten, beinhaltet PKCS11CardObjectID zusätzlich noch den Typ des Objekts ( private ” key“, public key“, certificate“, data“, secret key“). ” ” ” ” Die Klasse ist in der Abbildung 7.1 dargestellt. Zu den wichtigsten Funktionen der Klasse gehören statische Methoden zum Erzeugen einer PKCS11CardObjectID, die den symbolischen Namen des Objekts als Parameter übernehmen. Eine PKCS11CardObjectID muss zum Beispiel dann von der Anwendung instanziiert werden, wenn ein Objekt unter einer bestimmten Kennung auf der Karte gespeichert werden soll. Beispiel 7.1.1 (Speichern eines Datenobjekts unter angegebener Kennung). byte[] data = ...; CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.PKCS11ReaderDriver pkcs11.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); InitCardService initService = (InitCardService)smartcard.getCardService(InitCardService.class); CardObjectID dataID = PKCS11CardObjectID.constructDataObjectID("TCOS1-04".getBytes()); initS.writeData(data, dataID); //Daten werden unter "TCOS1-04" gespeichert 7.1.4 Konfiguration Die PKCS#11-Implementierung benötigt nur einen Konfigurationsparameter pkcs11Library“, ” der den Namen der nativen Bibliothek enthält. Der Parametername ist als Konstante in der 76 KAPITEL 7. IMPLEMENTIERUNGEN «interface» de.tud.cdc.cardservices.CardObjectID + equals(id: CardObjectID): boolean + toString(): String de.tud.cdc.cardservices.pkcs11.PKCS11CardObjectID - p11Id: byte[] - p11ObjectType: String + constructPrivateKeyObjectID(id: byte[]): PKCS11CardObjectID + constructPublicKeyCardObjectID(id: byte[]): PKCS11CardObjectID + constructCertificateObjectID(id: byte[]): PKCS11CardObjectID + constructDataObjectID(id: byte[]): PKCS11CardObjectID + constructSecretKeyObjectID(id: byte[]): PKCS11CardObjectID + PKCS11CardObjectID(id: byte[], objectType: String) + getID(): byte[] + getNumber(): int + getObjectType(): String + getSlotNr(): int + equals(id: CardObjectID) {implements} + isPrivateKey(): boolean + isPublicKey(): boolean + isCertificate(): boolean + isData(): boolean + isSecretKey(): boolean + toString(): String {implements} Abbildung 7.1: Die Klasse PKCS11CardObjectID mit ihrer wichtigsten Funktionalität. 7.2. FRAMEWORK-SCHNITTSTELLE ZU PC/SC 77 Klasse PKCS11PropertyConstants definiert. Damit die in dieser Ausarbeitung aufgeführten Code-Beispiele und die Klassen im Paket de.tud.cdc.cardservices.examples korrekt funktionieren, muss die Konfigurationsdatei pkcs11.properties diesen Parameter enthalten. Sie sieht zum Beispiel so aus: pkcs11Library = kpkcs11hash.dll 7.1.5 Anforderungen an die Umgebung Um die PKCS#11-Implementierung des Frameworks zu benutzen, müssen die folgenden Dateien im System vorhanden sein: • Eine native PKCS#11-Bibliothek in java.library.path. • Der Java-PKCS#11-Provider p11.jar im Java-Classpath und die zugehörige Bibliothek in java.library.path. • FlexiCoreProvider-1.1.5p3.signed.jar (oder eine andere Version des FlexiProviders) und codec.jar im Java-Classpath, um PKCS#10-Zertifikatsanträge zu erstellen. 7.2 Framework-Schnittstelle zu PC/SC Das Paket de.tud.cdc.cardservices.pcsc implementiert eine Schnittstelle zu PC/SC unter Verwendung vom Java-Wrapper [jpc] für PC/SC. Diese Schnittstelle bietet die Möglichkeit, über jeden PC/SC-fähigen Kartenleser APDUs an die Smartcard zu senden. Sie kann zusammen mit einer APDU-Level-Implementierung (zum Beispiel für die TCOS2.0-Smartcard) verwendet werden. Der Nachteil vom Java-Wrapper [jpc] und somit auch von dieser Framework-Schnittstelle sind teilweise sehr strenge Lizenzbedingungen für die Nutzung der Software. 7.2.1 PCSCReaderDriver und PCSCCardSlot Diese Klassen realisieren die im Paket de.tud.cdc.cardservices festgelegte Funktionalität und kapseln die wichtigsten Objekte des Java-Wrappers [jpc]. PCSCReaderDriver erweitert die Klasse de.tud.cdc.cardservices.ReaderDriver. Die Methode open initialisiert ein Context. Die Funktion getSlotList liefert ein Array von PCSCCardSlots zurück. PCSCCardSlot implementiert das Interface de.tud.cdc.cardservices.CardSlot und kapselt ein Context-Objekt und den Namen des Kartenlesers. Die Methode getCard liefert eine in der Konfiguration angegebene Card zurück. Wenn es sich dabei um eine ApduChannelCard handelt, wird sie mit einem PCSCCardChannel-Objekt initialisiert, sonst 78 KAPITEL 7. IMPLEMENTIERUNGEN wird ein Exception geworfen. Für ein PCSCCardSlot existiert nur eine ApduChannelCard, d.h. es wird höchstens ein PCSCCardChannel zur Karte geöffnet. 7.2.2 PCSCCardChannel PCSCCardChannel implementiert das Interface de.tud.cdc.cardservices.ApduChannel. In der Methode open wird die Verbindung zur Smartcard aufgebaut und ein PC/SC-CardObjekt erzeugt. Dieses wird dann dazu benutzt, APDUs mit der Smartcard auszutauschen. Die Klasse PCSCCardSlot agiert als Factory für PCSCCardChannels. 7.2.3 Konfiguration Die Framework-Schnittstelle zu PC/CS benötigt nur einen Konfigurationsparameter Card“, ” der angibt, welche ApduChannelCard-Implementierung verwendet werden soll. Der Parametername ist als Konstante in der Klasse PCSCPropertyConstants definiert. Damit die in dieser Ausarbeitung aufgeführten Code-Beispiele und die Klassen im Paket de.tud.cdc.cardservices.examples korrekt funktionieren, muss dieser Parameter in der Konfigurationsdatei enthalten sein. Sie sieht zum Beispiel so aus: Card = de.tud.cdc.cardservices.tcos20.TCOS20Card 7.2.4 Anforderungen an die Umgebung Um die Framework-Schnittstelle zu PC/SC zu benutzen, ist folgendes notwendig: • Ein PC/SC-Treiber für den Kartenleser. • Java-Wrapper [jpc] im Java-Classpath und die zugehörige Bibliothek in java.library.path. 7.3 Framework-Schnittstelle zu OCF Das Paket de.tud.cdc.cardservices.ocf implementiert eine Schnittstelle zu OCF. OCFTreiber existieren allerdings nur für wenige Kartenleser. Daher ist es sehr wichtig, dass die OCF-Schnittstelle auch die Möglichkeit bietet, über jeden PC/SC-fähigen Kartenleser APDUs an die Smartcard zu senden. Dabei findet der OCF-Wrapper für PC/SC Verwendung (s. Abschnitt 4.3 und [pcsa]). Da die Möglichkeiten, den PC/SC-Treiber aus einer Java-Umgebung anzusprechen, eingeschränkt sind (zum Beispiel durch Lizenzbedingungen bei JPC/SC [jpc]), gewinnt der OCF-Wrapper für PC/SC immer mehr an Bedeutung. Die Framework-Schnittstelle zu OCF kann zusammen mit einer APDU-Level-Implementierung (zum Beispiel für TCOS2.0-Smartcard) dazu verwendet werden, über PC/SC APDUs an die Karte zu senden. In späteren Versionen könnte man sich überlegen, eine Implementierung für native OCF-Bibliotheken vom Smartcard-Hersteller und vom Hersteller des Kartenlesers (CardServices und CardTerminals) zu entwickeln. 7.3. FRAMEWORK-SCHNITTSTELLE ZU OCF 7.3.1 79 OCFReaderDriver und OCFCardSlot Diese Klassen realisieren die im Paket de.tud.cdc.cardservices festgelegte Funktionalität und kapseln die wichtigsten Objekte des OCF. OCFReaderDriver erweitert die Klasse de.tud.cdc.cardservices.ReaderDriver. Die Methode open initialisiert das OCF mit den als Konfigurationsparameter übergebenen OCF-Bibliotheken und startet das OCF. Die Funktion getSlotList liefert ein Array von OCFCardSlots zurück. OCFCardSlot implementiert das Interface de.tud.cdc.cardservices.CardSlot und kapselt ein opencard.core.terminal.CardTerminal-Objekt. Die Methode getCard liefert eine in der Konfiguration angegebene Card zurück. Wenn es sich dabei um eine ApduChannelCard handelt, wird sie mit einem OCFPassThruCardChannel-Objekt initialisiert. Für ein OCFCardSlot existiert nur eine Card, d.h. es wird höchstens ein OCFPassThruCardChannel zur Karte geöffnet. 7.3.2 OCFPassThruCardChannel OCFPassThruCardChannel implementiert das Interface de.tud.cdc.cardservices.ApduChannel. Die Methode open erzeugt einen opencard.opt.util.PassThruCardService, welcher dazu benutzt wird, APDUs mit der Smartcard auszutauschen. Die Klasse OCFCardSlot agiert als Factory für OCFPassThruCardChannels. 7.3.3 Konfiguration Die Framework-Schnittstelle zu OCF benötigt die Konfigurationsparameter OpenCard.services“ ” und OpenCard.terminals“, die für die Initialisierung von OCF notwendig sind. Der Pa” rameter Card“ gibt an, welche Card-Implementierung verwendet werden soll. ” Die Parameternamen sind als Konstanten in der Klasse OCFPropertyConstants definiert. Damit die in dieser Ausarbeitung aufgeführten Code-Beispiele und die Klassen im Paket de.tud.cdc.cardservices.examples korrekt funktionieren, müssen diese Parameter in der Konfigurationsdatei enthalten sein. Um zum Beispiel APDUs an die TCOS2.0Smartcard über einen PC/SC-Treiber zu senden, muss die Konfigurationsdatei wie folgt aussehen: OpenCard.services = opencard.opt.util.PassThruCardServiceFactory OpenCard.terminals = com.ibm.opencard.terminal.pcsc10.Pcsc10CardTerminalFactory Card = de.tud.cdc.cardservices.tcos20.TCOS20Card 7.3.4 Anforderungen an die Umgebung Um die Framework-Schnittstelle zu OCF zu benutzen, muss das OpenCard Framework im System installiert sein [ocf]. Bei der Installation muss man beachten, dass unter Win- 80 KAPITEL 7. IMPLEMENTIERUNGEN dowsXP Microsoft Smart Card Base Components auf keinen Fall installiert werden sollen, obwohl dies von der Intallationssoftware vorgeschlagen wird. Die Komponente ist in der Standard-Distribution von WindowsXP vorhanden. Wird sie noch einmal im System installiert, so funktionieren PC/SC-Treiber nicht mehr. Deinstalation der Komponente ist nur durch ein System-Update möglich. Außerdem muss sich das Archiv base-core.jar im Java-Classpath befinden. Um OCF zu benutzen, ist weiterhin folgendes notwendig: 1. Für die Kommunikation mit der Smartcard über einen PC/SC-Treiber (Senden von APDUs): • Ein PC/SC-Treiber für den Kartenleser. • OCF-Wrapper für PC/SC installiert gemäß der Anleitung [pcsa]. 2. Für die Kommunikation mit der Smartcard über OCF-Treiber (ggf. in späteren Versionen): • Eine OCF-Bibliothek vom Smartcard-Hersteller (CardServices) im Java-Classpath, zum Beispiel tcos20.jar für die TCOS2.0-Smartcard. • Eine OCF-Bibliothek vom Hersteller des Kartenlesers (CardTerminals) im JavaClasspath, zum Beispiel kobil.jar für Kobil-Kartenleser. 7.4 APDU-Level-Implementierung für TCOS2.0-Smartcard Das Paket de.tud.cdc.cardservices.tcos20 enthält eine Implementierung für TCOS2.0Smartcards, die alle Framework-Funktionen auf der Kartenbetriebssystemebene realisiert. Dazu werden APDUs mit der Karte ausgetauscht. Diese Framework-Implementierung stellte den größten Entwicklungsaufwand dar, denn sie hat detailliertes Verständnis des Kartenbetriebssystems TCOS2.0 verlangt (die Betriebsdokumentation dazu findet man in [Pro01]). Außerdem müssen häufig mehrere APDUs konstruiert und an die Smartcard gesendet werden, um eine High-Level-Funktion zu realisieren. Diese Implementierung benutzt einen ApduChannel, um APDUs an die Karte zu übermitteln. Der ApduChannel wird von der Framework-Schnittstelle zu einer Kartenschnittstelle bereit gestellt, das kann zum Beispiel ein PCSCCardChannel oder ein OCFPassThruCardChannel sein. 7.4.1 TCOS20Card TCOS20Card erweitert die Klasse Card und stellt TCOS20CardServices zur Verfügung. Sie wird vom zugehörigen CardSlot mit einem ApduChannel und Konfigurationsparametern initialisiert. 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD 81 Die protected Methode getApduChannel macht den darunterliegenden ApduChannel für TCOS20CardServices dieser Karte zugänglich. Die Methode getName liefert TCOS20“ ” zurück. Mit diesem String beginnen auch alle CardService-Klassennamen, damit die Methode getCardService korrekt funktioniert (s. Abschnitt 6.2.2 2b). Die protected Funktion getSecurity liefert ein TCOS20Security-Object zurück, welches für Secure-Messaging dieser Smartcard zuständig ist und von ihren CardServices benutzt werden kann (s. Abschnitt 7.4.4). 7.4.2 TCOS20CardServices Die CardService-Hierarchie wird im Paket de.tud.cdc.cardservices.tcos20 vollständig implementiert. Die Klasse TCOS20CardService implementiert das Interface CardService und ist die Oberklasse für alle anderen TCOS2.0-CardServices. Alle TCOS20CardServices übernehmen bei der Instanziierung eine TCOS20Card als Argument und bekommen somit den Zugang zum ApduChannel und zu den Konfigurationsparametern. TCOS20CardServices benutzen viele Konfigurationsparameter (s. Abschnitt 7.4.6). Daher definiert die Klasse TCOS20CardService Methoden zum Auslesen von Properties in geeigneter Form (als String, Integer, Byte oder Byte-Array). Die friendly Methode setApduChannel kann bei der Realisierung von Secure-Messaging dazu verwendet werden, den von einem TCOS20CardService benutzen ApduChannel mit einem sicheren Kanal zu ersetzen (s. Abschnitt 7.4.4). Viele TCOS20CardServices bieten mehr Funktionalität als im implementierten Interface definiert ist. Die zusätzlichen Funktionen sind meist spezifisch für die COS-Ebene können benutzt werden, um einen Einblick in das Karteninnere zu gewinnen. So stellt zum Beispiel TCOS20CardInfoService die Methode listCardFileSystem zur Verfügung, welche die Hierarchie von Dateien und Verzeichnissen auf der Karte ausgibt. Die Methode listCardFileSystemDetails dieser Klasse gibt das Dateisystem der Karte inklusive alle Datei-Attribute aus. Um solche Funktionen zu benutzen, muss der CardService in den spezifischen Typ umgewandelt werden. Beispiel 7.4.1 (Ausgeben der Kartendateisystem). CardManager cm = CardManager.init( "de.tud.cdc.cardservices.pcsc.PCSCReaderDriver tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); for (int i = 0; i < cardSlots.length; i++) { Card smartcard = cardSlots[i].getCard(); TCOS20InfoCardService infoS = (TCOS20InfoCardService) smartcard .getCardService(InfoCardService.class); System.out.println("\nCard Serial Number: " + infoS.getSerialNumber()); 82 KAPITEL 7. IMPLEMENTIERUNGEN infoS.listCardFileSystem();}//Dateisystem der Karte wird ausgegeben Bei den CardService-Implementierungen gibt es folgende Besonderheiten: • TCOS20CASignatureCardService.sign kann nur dann korrekt ausgeführt werden, wenn der auf der Karte gespeicherte private Schlüssel der Signaturschlüssel der Karte ist. D.h. der Schlüssel gehört der Applikationsklasse “Signature“ an und besitzt die Schlüsselreferenz des lokalen Schlüssels mit der Nummer 0. TCOS2.0 unterstützt derzeit nur einen Signaturschlüssel. (s. [Pro01] S.77). • TCOS20SignatureCardService.sign kann dagegen auch dann korrekt ausgeführt werden, wenn der referenzierte private Schlüssel der Applikationsklasse “Encryption“ angehört und nicht die Schlüsselreferenz des lokalen Schlüssels mit der Nummer 0 besitzt. Dadurch wird die Möglichkeit geschaffen, dass mehrere Schlüssel zum Signieren benutzt werden. • In TCOS20InitCardService.generateKeyPair wird ein UnsupportedCardOperationException geworfen, denn Schlüsselerzeugung auf der Karte wird von TCOS2.0 nicht unterstützt. 7.4.3 TCOS20CardFileID Da die Implementierung auf der Kartenbetriebssystemebene arbeitet, werden Objekte auf der Smartcard mit einem eindeutigen Pfad im Dateisystem referenziert. Dies wurde schon in der Klasse CardFileID implementiert. TCOS20CardFileID erweitert sie und erleichtert den Umgang mit den Dateien und Verzeichnissen der Karte. Sie kapselt die allgemeinen TCOS2.0-Datei-Attribute und Informationen über die Dateistruktur. Von TCOS20CardFileID erben TCOS20KeyCardFileID und TCOS20PasswordCardFileID, welche auf das Arbeiten mit Schlüssel- und Passwortfiles ausgerichtet sind. Diese Klassen kapseln die für Schlüssel und Passwörter spezifische Attribute. Die Klassenhierarchie ist in der Abbildung 7.2 dargestellt. Zu den wichtigsten Funktionen dieser Klassengruppe gehören statische Methoden zum Erzeugen einer TCOS20CardFileID. Dazu gehören: • constructCartificateFileID • constructDataFileID • constructPublicKeyFileID • constructPrivateKeyFileID Die Methodenargumente haben die folgende Bedeutung: • CardFilePath appDir: Pfad zum DF, in dem die Datei angelegt werden soll 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD «interface» de.tud.cdc.cardservices.CardObjectID + equals(anId: CardObjectID): boolean + toString(): String 83 de.tud.cdc.cardservices.CardFileID - path: opencard.opt.iso.fs.CardFilePath + CardFileID(path: CardFilePath) + equals (anId: CardObjectID): boolean + getFilePath(): CardFilePath + isGlobal(): boolean + isLocal(): boolean + toString(): String de.tud.cdc.cardservices.tcos20.TCOS20CardFileID - atts: Hashtable - secAtts: TCOS20SecurityAttribute[] + constructCertificateFileID(appDir: CardFilePath, cert: java.security.cert.Cerfiticate, protectingPasswordNr: int): TCOS20CardFileID + constructDataFileID(appDir: CardFilePath, fileId: byte[], data: byte[] protectingPasswordNr: int): TCOS20CardFileID + TCOS20CardFileID(path: CardFilePath, atts: Hashtable) + get(attributeTag: byte): byte + getFileID(): byte + getFileStructure(): String + getParentDF(): CardFilePath + getRecordSize(): int + isRecordLinear(): boolean + isTransparent(): boolean + isPrivate(): boolean de.tud.cdc.cardservices.tcos20.TCOS20KeyCardFileID + constructPrivateKeyFileID(appDir: CardFilePath, fileId: byte[], keyNr: int, key: java.security.PrivateKey, forAuth: boolean, forEnc: boolean, forSign: boolean, protectingPasswordNr: int): TCOS20KeyCardFileID + constructPublicKeyFileID(appDir: CardFilePath, fileId: byte[], keyNr: int, key: java.security.PublicKey, forAuth: boolean, forEnc: boolean, forSign: boolean, protectingPasswordNr: int): TCOS20KeyCardFileID + TCOS20KeyCardFileID(path: CardFilePath, atts: Hashtable) + getKeyNr(): int + getType(): String + canAuth(): boolean + canEnc(): boolean + canSign(): boolean + canMac(): boolean + isPrivateKey(): boolean + isPublicKey(): boolean + isSecretKey(): boolean de.tud.cdc.cardservices.tcos20.TCOS20PasswordCardFileID + TCOS20PasswordCardFileID(path: CardFilePath, atts: Hashtable) + getCounterStartValue(): int + getPasswordNr(): int Abbildung 7.2: Klassen TCOS20CardFileID, TCOS20KeyCardFileID TCOS20PasswordCardFileID mit ihrer wichtigsten Funktionalität. und 84 KAPITEL 7. IMPLEMENTIERUNGEN • byte[] fileId: 2 Byte lange lokal eindeutige Dateikennung • int keyNr: lokal eindeutige Schlüsselnummer • int protectingPasswordNr: Nummer eines globalen Passworts, falls die Datei geschützt werden soll. Zu diesem Zweck können Passwörter 0 bis 3 verwendet werden. Wenn kein Passwortschutz erwünscht ist, soll eine negative Zahl übergeben werden. • boolean forAuth: der Schlüssel gehört der Applikationsklasse Authenticate“ an. ” • boolean forEnc: der Schlüssel gehört der Applikationsklasse Encryption“ an. ” • boolean forSign: der Schlüssel gehört der Applikationsklasse Signature“ an. ” Eine TCOS20CardFileID muss zum Beispiel dann von der Anwendung instanziiert werden, wenn ein Objekt unter einem bestimmten Pfad auf der Karte gespeichert werden soll. TCOS20PasswordCardFileIDs müssen von der Anwendung nicht erzeugt werden, denn das Anlegen von Passwortdateien geschieht in den Methoden PasswordCardService.initializePIN und PasswordCardService.initializePUK. Daher enthält die Klasse TCOS20PasswordCardFileID keine statische Methode constructPasswortFileID. Beispiel 7.4.2 (Speichern eines Schlüsselpaares unter angegebener Kennung). java.security.interfaces.RSAPrivateKey privateKey = ...; java.security.interfaces.RSAPublicKey publicKey = ...; CardManager cm = CardManager.init( "de.tud.cdc.cardservices.ocf.OCFReaderDriver opencard.properties tcos20.properties"); CardSlot[] cardSlots = cm.getSlotList(); Card smartcard = cardSlots[0].getCard(); InitCardService initService = (InitCardService)smartcard.getCardService(InitCardService.class); CardFilePath appDir = new CardFilePath(":3f00:4101"); byte[] fileID = new byte[]{(byte)0x51,(byte)0x00}; int keyNr = 0; boolean forAuth = false; boolean forEnc = false; boolean forSign = true; int protectingPasswordNr = init.getPropertyInt(TCOS20PropertyConstants.PIN_PASSWORD_NR); //privater Schlüssel wird mit der PIN geschützt CardObjectID privateKeyId = TCOS20KeyCardFileID.constructPrivateKeyFileID(appDir, fileID, keyNr, privateKey, forAuth, forEnc, forSign, protectingPasswordNr); 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD 85 initService.login("000815".getBytes()); //PIN ist 000815 initService.writeKeyPair(privateKey, publicKey, privateKeyId); 7.4.4 Secure-Messaging TCOS2.0-Implementierung zeigt einen Lösungsweg auf, wie Secure-Messaging für APDULevel-Implementierungen des Frameworks realisiert werden kann. Dazu sind zwei Klassen notwendig, eine Realisierung des Secure-Messaging, die das Interface ApduChannel implementiert, und eine Implementierung vom Interface Security (s. Abschnitt 6.5.4). Im Paket de.tud.cdc.cardservices.tcos20 sind es die Klassen TCOS20SecureMessaging und TCOS20Security. TCOS20SecureMessaging bietet ein Grundgerüst für die Realisierung des Secure- Messaging für TCOS2.0, das in späteren Versionen vervollständigt werden soll (s. Abschnitt 8.1.1). Ein detailliertes UML-Klassendiagramm findet man in der Abbildung 7.3. Das Klassenattribut authKey ist der gemeinsame geheime Schlüssel, der zur wechselseitigen Authentifikation von Smartcard und Applikation benutzt wird (s. auch Abschnitt 8.7 in [CEN04]). Der Konstruktor übernimmt einen ApduChannel, welcher zum Übertragen von verschlüsselten und authentifizierten APDUs benutzt wird. Dieser wird von der Methode getUsedChannel zurückgeliefert. Außerdem wird eine TCOS20SecureMessaging-Instanz mit einem Verschlüsselungsschlüssel encKey, einem MAC-Schlüssel macKey und den Kennungen dieser Objekte auf der Karte initialisiert. Wenn der Konstruktor TCOS20SecureMessaging(ApduChannel usedChannel, Properties props) benutzt wird, wird ein Session-Key für Secure-Messaging verwendet. Dieser wird von der Methode getSessionKey zurück geliefert. Die Methode eSignAuthenticate sollte die wechselseitige Authentifikation von Smartcard und Applikation durchführen. Sie ist nötig, wenn für die Benutzung der SecureMessaging-Schlüssel die Kenntnis des Authentifikationsschlüssels nachgewiesen werden muss. Die Funktion initEsignAuthenticate erzeugt bzw. überprüft auf die formale Korrektheit die Authentifikationsparameter. Dazu werden Methoden get8ByteChallenge und get8ByteRandom verwendet. In den Methoden mseGivenKeys und mseSessionKey wird die Sicherheitsumgebung der Karte für Secure-Messaging eingestellt. Dies geschieht mit dem Befehl MANAGE SECURITY ENVIROMENT (s. Tabelle 2.1). In der Methode send wird eine Command-APDU zunächst verschlüsselt bzw. mit der MAC-Prüfsumme versehen und über den (unsicheren) usedChannel an die Smartcard gesendet. Anschließend wird die MAC-Prüfsumme der empfangenen Response-APDU verifiziert bzw. die Antwortdaten werden entschlüsselt. 86 KAPITEL 7. IMPLEMENTIERUNGEN «interface» de.tud.cdc.cardservices.ApduChannel + open() + close() + isOpen(): boolean + sendCommandApdu(apdu: CommandApdu): ResponseApdu + getNativeObject(): Object de.tud.cdc.cardservices.tcos20.TCOS20SecureMessaging - eSignKey: byte[] - iccRandom: byte[] - iccSerial: byte[] - ifdRandom: byte[] - ifdSerial: byte[] - encKey: byte[] - macKey: byte[] - encKeyId: TCOS20KeyCardFileID - macKeyId: TCOS20KeyCardFileID - usedChannel: ApduChannel TCOS20SecureMessaging(usedChannel: ApduChannel, props: Properties) TCOS20SecureMEssaging(usedChannel: ApduChannel, props: Properties, encKey: byte[], encKeyId: TCOS20KeyCardFileID, macKey: byte[], macKeyId: TCOS20KeyCardFileID ) TCOS20SecureMessaging + open() {implements} + close() {implements} + isOpen(): boolean {implements} + eSignAuthenticate(idfRandom: byte[], iccRandom: byte[], ifdSerial: byte[], iccSerial:byte[], eSignKeyId: TCOS20KeyFileID ) + sendCommandApdu(apdu: CommandApdu): ResponseApdu {implements} + getNativeObject(): Object {implements} # getUsedChannel(): ApduChannel - generate8ByteRandom(): byte[] - get8ByteChallenge(): byte[] - getSessionKey(): byte[] - initEsignAuthenticate(ifdRandom: byte[], iccRandom: byte[], ifdSerial: byte[], iccSerial: byte[], eSignKeyId: CardObjectRef) # mseGivenKeys() # mseSessionKey() - wipe() Abbildung 7.3: Die Klasse TCOS20SecureMessaging 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD 87 Die Funktion wipe setzt alle verwendeten Parameter und Geheimnisse (eSignKey, ifdRandom, iccRandom, ifdSerial, iccSerial, encKey, macKey etc.) auf null, damit sie nachdem Beenden von Secure-Messaging nicht aus dem Speicher ausgelesen werden können. TCOS20Security implementiert das Interface Security (s. Abschnitt 6.5.4). In der Methode establishSecureMessaging wird TCOS20SecureMessaging initialisiert und der von dem CardService benutzte ApduChannel wird damit ersetzt. Die Funktion endSecureMessaging beendet Secure-Messaging für den angegebenen CardService. Der verwendete TCOS20SecureMessaging-Kanal wird geschlossen und mit dem ursprünglichen unsicheren Kanal ersetzt. TCOS20SecurePasswordCardService erweitert die Klasse TCOS20PasswordCardService und setzt Secure-Messaging für die Übertragung der Kartenpasswörter ein. Ein TCOS20SecurePasswordCardService wird mit dem zugehörigen TCOS20Card-Objekt initialisiert. Somit hat er auch einen Zugang zu Security dieser TCOSCard über die Methode TCOS20Card.getSecurity. TCOS20SecurePasswordCardService überschreibt die Methoden von TCOS20PasswordCardService, welche Passwörter zur Karte übertragen, auf die folgende Art: 1. Es wird eine Secure-Messaging-Session geöffnet. 2. Die Übertragung des Passwortes wird ausgeführt. 3. Dies Secure-Messaging-Session wird geschlossen. Für die Methode verifyGlobalPassword zum Beispiel sieht es wie folgt aus: protected void verifyGlobalPassword(byte passwordNr, byte[] password) throws CardException { security.establishSecureMessaging(this, authKey, authKeyId, encKey, encKeyId, macKey, macKeyId); super.verifyGlobalPassword(passwordNr, password); security.endSecureMessaging(this); } In der aktuellen Implementierung werden die Schlüssel und Schlüsselfile-Kennungen aus der Konfigurationsdatei eingelesen. In späteren Versionen kann dies auf eine andere Weise implementiert werden. 88 KAPITEL 7. IMPLEMENTIERUNGEN 7.4.5 Weitere Klassen TCOS20SecurityAttribute erleichtert die Handhabung der Sicherheitsattribute von Dateien und Verzeichnissen. Der Aufbau von TCOS2.0-Sicherheitsattributen ist in [Pro01] zu finden. Die statische Methode getSecurityAttributes wandelt ein Byte-Array in ein Array von TCOS20SecurityAttributes. Außerdem bietet die Klasse verschiedene Konstruktoren zum Aufbau von Sicherheitsattributen mit unterschiedlichen Eigenschaften. Die Methode isPasswordProtected liefert true zurück, wenn für die Ausführung des Kommandos eine Authentifikation durch Passworteingabe erforderlich ist. TCOS20Util stellt Werkzeuge zum Arbeiten mit EFs und DFs auf der APDU-Ebene. Alle Methoden der Klasse sind statisch und übernehmen einen ApduChannel als Parameter, der die Kommunikation mit der Karte vermittelt. Die meisten Funktionen von TCOS20Util sind selbsterklärend. TCOS20Constants speichert Konstanten des TCOS2.0-Kartenbetriebssystems, die den Aufbau von Command-APDUs und die Interpretation von Response-APDUs den anderen Klassen des Pakets vereinfachen. Die statische Methode decodeInstruction funktioniert analog zu der gleichnamigen Methode der Klasse CommandApdu und unterstützt auch propiertäre Befehle von TCOS2.0. Die Methode encodeInstuction liefert das InstructionByte zu einem Kommandonamen gefolgt von and“ oder or“, was bei dem Aufbau von ” ” Sicherheitsattributen gebraucht werden kann. 7.4.6 Konfiguration Da diese Implementierung auf der APDU-Ebene arbeitet, werden relativ viele Konfigurationsparameter benötigt. Die Parameternamen sind als Konstanten in der Klasse TCOS20PropertyConstants definiert: • PINPasswordNr (1 Byte): Nummer des PIN-Passwortes. • PINCounterStartValue (1 Byte): Startwert des FBZ der PIN. • FileIdPIN (2 Bytes): File Identifier der PIN-Passwortdatei, die sich im MF befindet. • PUKPasswordNr (1 Byte): Nummer des PUK-Passwortes. • PUKCounterStartValue(1 Byte): Startwert des FBZ der PUK. • FileIdPUK (2 Bytes): File Identifier der PUK-Passwortdatei, die sich im MF befindet. • TransportPIN: Die Nullpin der Karte mit einer Mindestlänge von sechs Bytes. 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD 89 • FileIdGDO (2 Bytes): File Identifier der GDO-Datei, die sich im MF befindet. • FileIdAppDir (2 Bytes): File Identifier des Applikationsverzeichnisses. • DirNameAppDir (7 Bytes): Ein in der gesamten Karte eindeutiger Verzeichnisname des Applikationsverzeichnisses (FileIdAppDir). • FileIdFirstCertificate (2 Bytes): File Identifier des ersten Zertifikats auf der Karte. Für weitere Zertifikate wird der File Identifier um eins inkrementiert. Alle Zertifikate werden in dem Verzeichnis gespeichert, wo der zugehörige öffentliche Schlüssel sich befindet. • FileIdFirstPublicKey (2 Bytes): File Identifier des ersten öffentlichen Schlüssels auf der Karte. Für weitere öffentliche Schlüssel wird der File Identifier um eins inkrementiert. Alle Schlüsselpaare werden im Applikationsverzeichnis (FileIdAppDir) gespeichert, wenn es nicht explizit anders angegeben ist. • FileIdFirstPrivateKey (2 Bytes): File Identifier des ersten privaten Schlüssels auf der Karte. Für weitere private Schlüssel wird der File Identifier um eins inkrementiert. Alle Schlüsselpaare werden im Applikationsverzeichnis (FileIdAppDir) gespeichert, wenn es nicht explizit anders angegeben ist. • KeyNrFirstKeyPair (1 Byte): Nummer des ersten Schlüsselpaares im Applikationsverzeichnis (FileIdAppDir). Für weitere Schlüsselpaare wird die Nummer um eins inkrementiert. • FileIdAuthKeySM (2 Bytes): File Identifier des authKey (s. Abschnitt 7.4.4), der sich im MF befindet. Reserviert für die Implementierung des Secure-Messaging. • FileIdEncKeySM (2 Bytes): File Identifier des encKey (s. Abschnitt 7.4.4), der sich im MF befindet. Reserviert für die Implementierung des Secure-Messaging. • FileIdMacKeySM (2 Bytes): File Identifier des macKey (s. Abschnitt 7.4.4), der sich im MF befindet. Reserviert für die Implementierung des Secure-Messaging. • authKeySM : Authentifikationsschlüssel authKey (s. Abschnitt 7.4.4) für Secure-Messaging. Reserviert für die Implementierung des Secure-Messaging. • encKeySM : Verschlüsselungsschlüssel encKey (s. Abschnitt 7.4.4) für Secure-Messaging. Reserviert für die Implementierung des Secure-Messaging. • macKeySM : MAC-Schlüssel authKey (s. Abschnitt 7.4.4) für Secure-Messaging. Reserviert für die Implementierung des Secure-Messaging. 90 KAPITEL 7. IMPLEMENTIERUNGEN Damit die in dieser Ausarbeitung aufgeführten Code-Beispiele und die Klassen im Paket de.tud.cdc.cardservices.examples korrekt funktionieren, muss die Konfigurationsdatei tcos20.properties diese Parameter enthalten. Sie sieht zum Beispiel so aus: Card = de.tud.cdc.cardservices.tcos20.TCOS20Card # für den zugehörigen CardSlot (PCSCCardSlot oder OCFCardSlot) PasswordCardService = TCOS20SecurePasswordCardService # kann angegeben werden, um den sicheren Passwort-Service zu benutzen PINPasswordNr = 00 PINCounterStartValue = 03 FileIdPIN = 50 00 PUKPasswordNr = 01 PUKCounterStartValue = 03 FileIdPUK = 50 08 TransportPIN = 00 00 00 00 00 00 FileIdGDO = 2f 02 FileIdAppDir = 41 01 DirNameAppDir = d2 76 00 01 05 00 01 FileIdFirstCertificate = 43 52 FileIdFirstPublicKey = 4e 03 FileIdFirstPrivateKey = 51 03 KeyNrFirstKeyPair = 03 FileIdAuthKeySM = 44 00 #reserved for future use FileIdEncKeySM = 44 00 #rfu FileIdMacKeySM = 44 00 #rfu authKeySM = 5D AD 7A BF 80 80 02 D3 F2 4F 9E 80 80 4C 8C 3D #rfu encKeySM = 5D AD 7A BF 80 80 02 D3 F2 4F 9E 80 80 4C 8C 3D #rfu macKeySM = 5D AD 7A BF 80 80 02 D3 F2 4F 9E 80 80 4C 8C 3D #rfu Die Konfigurationsparameter können auch ohne Leerzeichen eingegeben werden; diese dienen nur der Übersichtlichkeit der Datei. Nicht alle Konfigurationsparameter sind für die Ausführung einer Operation auf der Karte erforderlich. Wenn zum Beispiel ein Aufruf von TCOS20InitCardService.createPUK erfolgt, so werden nur die Parameter Card, PUKPasswordNr, PUKCounterStartValue und FileIdPUK gebraucht. Falls eine sichere Passwortübertragung erwünscht ist, muss auch eine Implementierung PasswordCardService angegeben sein und eventuell FileIDAuthKeySM, FileIDEncKeySM, FileIDMacKeySM, authKeySM, encKeySM und macKeySM. Alle anderen Parameter sind in dem Fall nicht nötig. 7.4. APDU-LEVEL-IMPLEMENTIERUNG FÜR TCOS2.0-SMARTCARD 7.4.7 91 Anforderungen an die Umgebung Um die TCOS2.0-Implementierung des Frameworks zu benutzen, muss folgendes vorhanden sein: • Eine Framework-Kartenschnittstelle, die einen ApduChannel bereit stellt, zum Beispiel de.tud.cdc.cardservices.pcsc oder de.tud.cdc.cardservices.ocf. • Das OCF-Archiv base-opt.jar im Java-Classpath (für den Zugang zur Klasse opencard.opt.iso.fs.CardFilePath). • FlexiCoreProvider-1.1.5p3.signed.jar (oder eine andere Version des FlexiProviders) und codec.jar im Java-Classpath, um PKCS#10-Zertifikatsanträge zu erstellen. 92 KAPITEL 7. IMPLEMENTIERUNGEN Kapitel 8 Ausblick Im diesem Kapitel wird auf die Möglichkeiten der Weiterentwicklung und Erweiterung des Frameworks eingegangen. 8.1 Weiterentwicklung der Software 8.1.1 Implementierung des Secure-Messaging für TCOS2.0 Im Paket de.tud.cdc.cardservices.tcos20 wurde durch die Klassen TCOS20Security und TCOS20SecureMessaging ein Grundgerüst für die Implementierung des Secure-Messaging für TCOS2.0 vorbereitet (s. Abschnitt 7.4.4). Aufgrund des Zeitdrucks konnte SecureMessaging nicht vollständig realisiert werden. Um eine funktionierende Implementierung zu erhalten, müssen die folgenden Methoden der Klasse TCOS20SecureMessaging vervollständigt werden: • get8ByteChallenge: Anforderung einer Zufallszahl von der Chipkarte für die wechselseitige Authentifikation. • generate8ByteRandom: Generierung einer Zufallszahl für die wechselseitige Authentifikation. • eSignAuthenticate: Durchführung der wechselseitigen Authentifikation zwischen Applikation und Smartcard. • getSessionKey: Liefert den aktuellen Sitzungsschlüssel zurück, ist mit dem Kommando GET SESSION KEY von TCOS2.0 zu implementieren. • mseGivenKeys: Einstellung der Sicherheitumgebung der Karte für die Nutzung angegebener Schlüssel für Secure-Messaging. • mseGivenKeys: Einstellung der Sicherheitumgebung der Karte für die Nutzung des aktuellen Session-Key für Secure-Messaging. 93 94 KAPITEL 8. AUSBLICK • sendCommandApdu: Verschlüsselung bzw. MAC-Berechnung für Command-APDUs und Entschlüsselung bzw. MAC-Verifikation für Response-APDUs. Die entsprechenden Stellen sind im Quellcode markiert. Jedes TODO“-Etikett ist mit einer ” Beschreibung versehen. Details des Secure-Messaging von TCOS2.0 findet man in [Pro01]. 8.2 Anweisungen zur Software-Erweiterung Eine wichtige Eigenschaft der entwickelten Software ist deren Flexibilität und Erweiterbarkeit. In diesem Abschnitt wird gezeigt, wie Erweiterungen des Frameworks realisiert werden können. Es werden die wichtigsten Erweiterungsfälle betrachtet, Hinzunahme neuer CardServices bzw. Kartenobjekte und eine Implementierung des Frameworks für neue Smartcards und Kartenschnittstellen. 8.2.1 Hinzunahme neuer CardServices Die CardServices-Lösung ermöglicht Hinzunahme neuer Funktionalität ohne Codemodifikation — es genügt, einen neuen CardService zu definieren und zu implementieren oder einen bestehenden CardService zu erweitern. Möchte man zum Beispiel Entschlüsselung der Daten auf der Karte durchführen, so wären die folgenden Schritte notwendig: 1. Es wird ein Interface DecryptionCardService mit entsprechenden Methoden definiert. Da bei der Entschlüsselung auf private Schlüssel zugegriffen wird, muss eine Benutzerauthentifikation stattfinden. Daher soll DecryptionCardService das Interface LoginCardService erweitern. public interface DecryptionCardService extends LoginCardService { public byte[] decrypt(CardObjectRef privateKeyRef, byte[] data) throws CardException;} 2. Eine Realisierung des Interfaces wird einer Framework-Implementierung hinzugefügt, zum Beispiel PKCS11DecryptionCardService dem Paket de.tud.cdc.cardservices.pkcs11 oder TCOS20DecryptionCardService dem Paket de.tud.cdc.cardservices.tcos20. Es kann auch notwendig sein, neue Implementierungen bestehender CardServices zu entwickeln, die den eigenen Bedürfnissen und Anforderungen genau entsprechen. Diese können dann durch einen Eintrag in der Konfigurationsdatei ins Framework eingebunden werden. Soll zum Beispiel MyInitCardService, eine spezifische Implementierung des InitCardService, verwendet werden, so muss die Konfigurationsdatei den Eintrag InitCardService = MyInitCarService 8.2. ANWEISUNGEN ZUR SOFTWARE-ERWEITERUNG 95 enthalten. Die Klasse MyInitCardService und die zugehörige Card-Klasse müssen sich dann in einem Paket befinden. Ist dies nicht der Fall, so soll der Konfigurationseintrag den vollen Name der Implementierung enthalten: InitCardService = com.myimpl.MyTCOS20InitCarService 8.2.2 Hinzunahme neuer Kartenobjekte Das Framework unterstützt die Handhabung von privaten und öffentlichen Schlüsseln, Zertifikaten und Datenobjekten. Da die Klassen CardObjectRef und CardObjectID vom Kartenobjekttyp unabhängig sind, müssen keine neuen Typen definiert werden, um mit anderen Objekten auf der Karte zu arbeiten. Möchte man zum Beispiel mit symmetrischen Schlüsseln arbeiten, so sollen nur die entsprechenden Funktionen definiert und implementiert werden, zum Beispiel: • getSecretKeyRefs(): CardObjectRef[] • writeSecretKey(secretK: javax.crypto.SecretKey, secretKeyId: CardObjectID) • deleteSecretKey(secretKeyId: CardObjectID) An dieser Stelle sei bemerkt, dass die bestehenden Framework-Implementierungen die Möglichkeit bieten, CardObjectIDs für symmetrische Schlüssel bequem zu konstruieren. Das sind die statischen Funktionen PKCS11CardObjectID.constructSecretKeyID und TCOS20KeyCardFileID.constructSecretKeyFileID. 8.2.3 Implementierung für andere Smartcards und Kartenschnittstellen Bei den APDU-Level-Implementierungen können die verwendeten Framework-Komponenten in zwei Gruppen unterteilt werden: 1. Kartenspezifisch: (a) Eine Card-Klasse. (b) CardService-Implementierungen. (c) Eine CardObjectID-Implementierung oder Implementierungshierarchie. (d) Konfigurationsparameter der Smartcard. 2. Spezifisch für die Kartenschnittstelle: (a) Ein ReaderDriver. (b) Ein CardSlot. (c) Ein ApduChannel. 96 KAPITEL 8. AUSBLICK (d) Konfigurationsparameter der Kartenschnittstelle. Implementierungen auf der APDU-Ebene können sich den Frameworkschnittstellen zu PC/SC bedienen (Komponenten der Gruppe 2), falls ein PC/SC-Treiber für den Kartenleser vorhanden ist. In dem Fall müssen nur die kartenspezifische Komponenten implementiert werden. APDUs werden dann (analog zu TCOS2.0-Implementierung) über einen PCSCCardChannel oder einen OCFPassThruCardChannel mit der Smartcard ausgetauscht. Falls man eine andere Low-Level-Kartenschnittstelle hinzunehmen möchte, zum Beispiel CT-API, müssen die Komponenten der Gruppe 2 implementiert werden. Für eine High-Level-Schnittstelle müssen analog zur PKCS#11-Implementierung beide Komponentengruppen realisiert werden. Wenn man zum Beispiel mit OCF-fähigen Chipkarten direkt über einen OCF-Treiber kommunizieren möchte (und nicht über den OCF-Wrapper für PC/SC), soll das Paket de.tud.cdc.cardservices.ocf um die Komponenten der Gruppe 1 erweitert werden. Kapitel 9 Zusammenfassung In der vorliegenden Arbeit wurde Design und beispielhafte Implementierungen des entwickelten Frameworks vorgestellt, das eine flexible Anbindung von Chipkarten an eine Sicherheitsinfrastruktur gestattet. Anschtoß dazu gaben zwei bestehende selbstbediente Smartcard-Systeme, FlexiTrust Identity Management und TUDCard. Das Ziel ist gewesen, ein Software-Paket zur Anbindung von Chipkarten zu entwickeln, das weitestgehend unabhängig von Smartcard-Typen und Kartenschnittstellen den Anforderungen dieser und ähnlicher Systeme genügt. Im Laufe dieser Arbeit wurde das technische Umfeld analysiert und geeignete Abstraktionen für die verfügbaren Funktionen seitens der Hard- und Software gefunden. Die funktionale Anforderungen wurden orientiert an die Kriterien der Erweiterbarkeit und Flexibilität im Framework-Design umgesetzt. Das Framework unterstützt die typischen Prozesse der Anwendungsdomäne auf einem hohen Abstraktionsniveau. Es wurde eine Anwendungsarchitektur entwickelt, indem der Kontrollfluss der Anwendung und die Schnittstellen für die konkreten Klassen definiert wurden. Zusammengehörige Smartcard-Funktionen werden in Form von Smartcard-Diensten zur Verfügung gestellt. Die Implementierung eines Dienstes ist für die Anwendung transparent und kann jeder Zeit durch eine Veränderung der Konfigurationsdatei ausgetauscht werden. Neue Smartcard-Dienste können ohne Modifikation bestehender Klassen eingebunden werden. Das Framework wurde orientiert an die Kriterien der Verbreitung für die TCOS2.0Smartcard und die Kartenschnittstellen PKCS#11, PC/SC und OCF implementiert. Auf die Möglichkeiten der Weiterentwicklung und Erweiterung der Software wurde detailliert eingegangen. Die Software ist in einer Sicherheitsinfrastruktur direkt einsetzbar und kann mit minimiertem Aufwand an die eigene Bedürfnisse und Anforderungen angepasst werden. 97 98 KAPITEL 9. ZUSAMMENFASSUNG Literaturverzeichnis [CEN04] CEN Workshop Agreement CWA 14890-1. Application Interface for Smart Cards Used as Secure Signature Creation Devices - Part 1: Basic Requirements. ftp://ftp.cenorm.be/PUBLIC/CWAs/e-Europe/eSign/cwa14890-01- 2004-Mar.pdf, März 2004. [Cha99] D. W. Chadwick. Smart cards aren’t always the smart choice. IEEE Computer, 32(12):142–143, December 1999. [Clage] Claudia Eckert. IT-Sicherheit. Oldenburg Verlag, 2004, 3. Auflage. [Eri95] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides . Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995. [Fle] FlexSecure GmbH. Trustcenter Software FlexiTrust. http://www.flexsecure.de. [Her05] Hervé Seudié. Anwendung von Digitalen Identitäten an einer Hochschule. Diplomarbeit, TU Darmstadt, Januar 2005. [hsm] Hardware Security Modules. http://www.eracom-tech.com/hsm.0.html. [Isk05] Iskra Tomova. Card Manager: Entwurf und Implementierung. Studienarbeit, TU Darmstadt, Dezember 2005. [Joh] Johannes Buchmann. Skript zur Vorlesung Public-Key-Infrastrukturen, TU Darmstadt, Sommersemester 2005. http://www.cdc.informatik.tu- darmstadt.de/lehre/SS05/vorlesung/PKI/resources.html. [Johge] Johannes Buchmann. Einfürung in die Kryptographie. Springer Verlag, 2004, 3. Auflage. [Jol03] Jolyon Clulow. On Security of PKCS #11. In Cryptographic Handware and Embedded Systems - CHES 2003, volume LNCS 2779, pages 411–425. Springer, 2003. [jpc] JPC/SC Java API. http://www.musclecard.com/middle.html. 99 100 LITERATURVERZEICHNIS [KOB] KOBIL Systems GmbH. KOBIL SecOVID Version 3.1. http://www.kobil.de. [mkt] MKT Spezifikation Version 1.0. http://www.teletrust.de/index.php?id=303. [mus] MUSCLE - Movement for the Use of Smart Cards in a Linux Enviroment. http://www.linuxnet.com. [ocf] OpenCard. http://www.opencard.org. [pcsa] PC/SC CardTerminal für OCF. http://www.gemplus.com/techno/opencard /cardterminals/pcsc/download.html. [pcsb] PC/SC Workgroup. http://www.pcscworkgroup.com. [pki] Folien zur Vorlesung Public-Key-Infrastrukturen, TU Darmstadt, Sommersemester 2005. http://www.cdc.informatik.tu-darmstadt.de/lehre/SS05/vorlesung /PKI/resources.html. [Pro01] Produktbereich T-TeleSec Deutschen Telekom AG. Telesec Chipcard Operating System V2.0 Release 3. Deutsche Telekom AG, Januar 2001. [rfc] Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. http://www.ietf.org/rfc/rfc3280.txt. [RSAa] RSA Laboratries. PKCS#10: Certification Request Syntax Standard. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-10/pkcs-10v1 7.pdf. [RSAb] RSA Laboratries. PKCS#11: Cryptographic Token Interface Standard. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/v2-20/pkcs-11v2-20a1.pdf. [RSAc] RSA Laboratries. PKCS#12: Personal Information Exchange Syntax Standard. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf. [RSAd] RSA Laboratries. PKCS#15: Personal Information Exchange Syntax Standard. ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-15/pkcs-15v1 1.pdf. [RSAe] RSA Laboratries. PKCS#7: Cryptographic Message Syntax Standard. ftp://ftp.rsasecurity.com/pub/pkcs/ps/pkcs-7.ps. [tuda] TUDCard. http://www.tu-darmstadt.de/hrz/chipkarte. [tudb] TUDCard, Kartenlayout. http://www.tu-darmstadt.de/hrz/chipkarte/karte /karte layout.tud. [Vla00] Vlad Coroama. Entwurf und Implementierung eines Handware-Providers für Java Cryptography Architecture. Diplomarbeit, TU Darmstadt, März 2000. LITERATURVERZEICHNIS 101 [Wolge] Wolfgang Rankl, Wolfgang Effing. Handbuch der Chipkarten. Hanser Verlag, 2002, 4. Auflage.