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
[email protected]
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.