Java Smartcard Unterstützung unter Linux Autoren: Dozent: Diplomarbeit: Zeitraum: Jan Keller, KI00 Carla Schaffner, KI00 Prof. Dr. Andreas Steffen DA Sna 03/3 5. September 2003 – 27. Oktober 2003 Java Smartcard Unterstützung unter Linux Inhaltsverzeichnis Inhaltsverzeichnis Legal Disclaimer ............................................................................................................... V Aufgabenstellung ........................................................................................................... VI Zusammenfassung ........................................................................................................VII Abstract.......................................................................................................................... VIII 1. Einleitung.................................................................................................................... 1 2. Projektplanung .......................................................................................................... 2 2.1. 2.2. 3. Pflichtenheft ............................................................................................................... 4 3.1. 3.2. 4. Netzplan .......................................................................................................................... 2 Projektablaufplan........................................................................................................... 3 Funktionale Anforderungen......................................................................................... 4 Nicht‐funktionale Anforderungen .............................................................................. 4 Grundlagen ................................................................................................................. 5 4.1. Hashfunktion.................................................................................................................. 5 4.2. Zertifikate........................................................................................................................ 5 4.3. Kryptographie ................................................................................................................ 6 4.3.1. Verschlüsseln (Encrypt) ....................................................................................... 8 4.3.2. Entschlüsseln (Decrypt)........................................................................................ 9 4.3.3. Signieren (Sign) ..................................................................................................... 9 4.3.4. Verifizieren (Verify) ............................................................................................ 10 4.4. Smartcards .................................................................................................................... 11 4.4.1. Was sind Smartcards .......................................................................................... 11 4.4.2. Einsatzgebiet der Smartcards ............................................................................ 11 4.4.3. Filesystem der Smartcards ................................................................................. 12 4.5. PC / SC........................................................................................................................... 17 4.6. Padding ......................................................................................................................... 20 4.6.1. PKCS#1 v1.5 Padding ......................................................................................... 20 4.6.2. RSA OAEP............................................................................................................ 21 4.6.3. RSA PSS ................................................................................................................ 22 4.7. Digest Info..................................................................................................................... 24 5. Problemanalyse........................................................................................................ 26 5.1. Use Cases ...................................................................................................................... 26 5.1.1. Zertifikate von der Smartcard lesen ................................................................. 26 5.1.2. Signatur erstellen................................................................................................. 26 5.1.3. Signatur verifizieren ........................................................................................... 27 5.2. PKCS#11 / Cryptoki ..................................................................................................... 27 5.3. OpenSC.......................................................................................................................... 27 5.4. Java Native Interface (JNI).......................................................................................... 28 5.5. Java Cryptography Architecture / Extension (JCA /JCE) ....................................... 28 Jan Keller Carla Schaffner I 24.10.2003 Java Smartcard Unterstützung unter Linux 6. Inhaltsverzeichnis Lösungskonzepte ..................................................................................................... 29 6.1. 6.2. 6.3. 6.4. 6.5. 6.6. 6.7. 6.8. 6.9. 6.10. 6.11. 6.12. 6.13. 7. Übersicht ....................................................................................................................... 29 Lösungsvarianten......................................................................................................... 30 PC / SC Implementation.............................................................................................. 31 Zustandsdiagramm der Smartcard ........................................................................... 32 PKCS#11 API ................................................................................................................ 33 C_Sign / pMechanism.................................................................................................. 35 Digest Info in OpenSC................................................................................................. 36 Makros in C................................................................................................................... 37 Implementierung des Java Native Interface ............................................................ 39 Implementierung des Providers ................................................................................ 42 Kommunikation der Komponenten .......................................................................... 43 Klassendiagramme ...................................................................................................... 45 Sequenzdiagramme ..................................................................................................... 46 Verwendete Komponenten.................................................................................... 48 7.1. Hardware ...................................................................................................................... 48 7.1.1. Cryptoflex 8k ....................................................................................................... 48 7.1.2. Reflex 72 V2 RS232 Reader................................................................................. 48 7.2. Software......................................................................................................................... 49 7.2.1. Java Klassen ......................................................................................................... 49 7.2.2. C............................................................................................................................. 53 8. Tests............................................................................................................................ 55 8.1. 8.2. 8.3. 8.4. 8.5. 9. SignatureWithRSA.class ............................................................................................. 55 CertificateFactoryX509.class ....................................................................................... 59 CertificateReader.class ................................................................................................ 61 Util.class ........................................................................................................................ 63 JNIForJLinProvider.class ............................................................................................ 64 Probleme.................................................................................................................... 69 9.1. ASCII to Hex................................................................................................................. 69 9.1.1. C............................................................................................................................. 69 9.1.2. Java ........................................................................................................................ 71 9.2. Entschlüsseln mit C_Decrypt ..................................................................................... 72 9.3. JCE.................................................................................................................................. 73 9.3.1. Service CertificateFactory .................................................................................. 73 9.3.2. Entscheid und Lösung........................................................................................ 74 9.4. Signieren des Providers .............................................................................................. 75 9.5. Digest Info..................................................................................................................... 76 9.6. Verwenden der mitgelieferten OpenSC Files .......................................................... 76 10. Verwendung des Providers ................................................................................... 77 10.1. 10.2. 10.3. 10.4. 10.5. Dynamisches Einbinden ............................................................................................. 77 Statisches Einbinden.................................................................................................... 77 Service Signature des Providers benützen ............................................................... 78 Service CertificateFactory des Providers benützen................................................. 79 Verifizieren der erstellten Signatur ........................................................................... 80 Jan Keller Carla Schaffner II 24.10.2003 Java Smartcard Unterstützung unter Linux Inhaltsverzeichnis 11. Offene Punkte .......................................................................................................... 82 12. Schlusswort............................................................................................................... 82 Anhang .............................................................................................................................. 83 A. Glossar ............................................................................................................................... 83 B. Rückgabewerte PKCS#11 ................................................................................................ 91 C. Source Code ...................................................................................................................... 93 D. CD Inhaltsverzeichnis...................................................................................................... 93 E. Quellenverzeichnis........................................................................................................... 94 E.1. Bücher ................................................................................................................... 94 E.2. Links...................................................................................................................... 94 E.3. Bezugsperson....................................................................................................... 95 F. Installationsanleitung ...................................................................................................... 96 G. Betriebs‐ / Konfigurationsanleitung ............................................................................ 100 H. Beispielanwendung........................................................................................................ 101 Jan Keller Carla Schaffner III 24.10.2003 Java Smartcard Unterstützung unter Linux Abbildungsverzeichnis Abbildungsverzeichnis Abbildung 1: Vorgang verschlüsseln ................................................................................................. 8 Abbildung 2: Vorgang entschlüsseln ................................................................................................. 9 Abbildung 3: Vorgang signieren........................................................................................................ 9 Abbildung 4: Vorgang verifizieren .................................................................................................. 10 Abbildung 5: Filestruktur cryptoflex‐eraser .................................................................................... 13 Abbildung 6: PKCS#15 Filestruktur ............................................................................................... 13 Abbildung 7: Karte mit Zertifikat und Private Key......................................................................... 14 Abbildung 8: Zeiger‐ und Datenfiles ............................................................................................... 15 Abbildung 9: PC/SC‐Architektur .................................................................................................... 17 Abbildung 10: Paddingvorgang bei PKCS#1 v1.5 .......................................................................... 20 Abbildung 11: Paddingvorgang bei OAEP ..................................................................................... 22 Abbildung 12: Paddingvorgang bei PSS ......................................................................................... 23 Abbildung 13: Padding mit Digest Info .......................................................................................... 24 Abbildung 14: Übersicht.................................................................................................................. 29 Abbildung 15: Implementierung PC/SC ......................................................................................... 31 Abbildung 16: Smartcard‐Zustandsdiagramm................................................................................ 32 Abbildung 17: Kommunikation der Komponenten .......................................................................... 44 Abbildung 18:Klasse KelschaJLinProvider ...................................................................................... 45 Abbildung 19:Klasse CertificateFactoryX509.................................................................................. 45 Abbildung 20: Klasse SignatureWithRSA ...................................................................................... 45 Abbildung 21: Klasse Util................................................................................................................ 46 Abbildung 22:Klasse JNIForJLinProvider ....................................................................................... 46 Abbildung 23: Sequenzdiagramm Service CertificateFactory ......................................................... 46 Abbildung 24: Sequenzdiagramm Service Signature ...................................................................... 47 Abbildung 25: Hilfsarray ................................................................................................................. 70 Abbildung 26: CBC.......................................................................................................................... 84 Abbildung 27: ECB .......................................................................................................................... 85 Abbildung 28: Java Installation ....................................................................................................... 96 Abbildung 29: openssl Installation .................................................................................................. 96 Abbildung 30: Deinstallation PC/SC Lite Treiber........................................................................... 97 Abbildung 31: Treiber und Module ................................................................................................. 97 Abbildung 32: Benötigte .so‐Files .................................................................................................... 98 Abbildung 33: LD_LIBRARY_PATH............................................................................................. 99 Abbildung 34: Client‐ / Server‐Gui ............................................................................................... 101 Abbildung 35: Randomzahl senden ............................................................................................... 102 Abbildung 36: Zertifikate und Randomzahl .................................................................................. 102 Abbildung 37: Leeres Parameter‐Gui ............................................................................................ 103 Abbildung 38: Ausgefülltes Parameter‐Gui .................................................................................. 103 Abbildung 39: Nach dem Signaturvorgang................................................................................... 103 Abbildung 40: Verification successful............................................................................................ 104 Abbildung 41: Verification failed ................................................................................................... 104 Jan Keller Carla Schaffner IV 24.10.2003 Java Smartcard Unterstützung unter Linux Vorspann Legal Disclaimer © 2003 Zürcher Hochschule Winterthur (ZHW). Alle Rechte vorbehalten. Kein Teil der vorliegenden Dokumentation darf ohne schriftliche Genehmigung der Autoren oder der ZHW in irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes mechanisches oder elektronisches Verfahren), auch nicht für Zwecke der Unterrichtsgestaltung reproduziert oder unter Verwendung elektronischer Systeme gespeichert, verarbeitet, vervielfältigt oder verbreitet werden. Die Autoren sowie die ZHW übernehmen keine Gewähr für die Richtigkeit der Angaben in dieser Arbeit. Im Weiteren haften die Autoren oder die ZHW unter keinen Umständen für mittelbare oder unmittelbare Folgeschäden oder besondere Schadensfolgen, die sich aus oder in Verbindung mit dieser Dokumentation ergeben, gleichgültig, ob diese auf‐ grund unerlaubter Handlungen, eines Vertrages oder sonstigen Gründen in Verbindung mit dieser Dokumentation entstehen. Firmen‐ und Produktenamen die in dieser Dokumentation erwähnt und/oder verwendet werden, sind Warenzeichen oder/und Markenzeichen von den zugehörigen Firmen. Hinweis Um den Lesefluss zu verbessern, wird auf die weibliche Form verzichtet. Selbstverständ‐ lich sind männliche und weibliche Personen gleichermassen angesprochen. Jan Keller Carla Schaffner V 24.10.2003 Java Smartcard Unterstützung unter Linux Vorspann Aufgabenstellung Schlussdiplomprüfung Praktische Diplomarbeit Dozent: Prof. Dr. Andreas Steffen Studiengang: KI Jahr: 2003 Studierende: Jan Keller Ausgabe: 5. September 2003 Carla Schaffner Abgabe: 27. Oktober 2003 Beschreibung: Das OpenSC Projekt (http://www.opensc.org) erlaubt es, Smartcards und Cryptotoken über eine herstellerunabhängige PC/SC Schnittstelle unter dem Linux Betriebssystem an‐ zusprechen. Mit dem PKSC#11 „Cryptographic Token Interface Standard“ existiert ein normiertes, C‐basiertes API mit dessen Hilfe kryptographische Operationen auf die Smartcard ausgelagert werden können. In der vorgeschlagenen Diplomarbeit soll auf der Basis des bestehenden PKCS#11 APIs ein Cryptographic Service Provider (CPS) unter Java zur Verfügung gestellt werden, in dem die C‐Funktionsaufrufe von OpenSC in ein Java Native Interface (JNI) eingebettet werden. Die dadurch gewonnene Java Smartcard Unterstützung unter Linux kann dann zum Beispiel im Rahmen des Apache XML Security Projekts (http://xml.apache.org /security) verwendet werden, um XML Signaturen zu erstellen. Ziele: • Verstehen der Java Cryptography Extension (JCE) • Verstehen der PKCS#11 Schnittstelle • Erstellen eines Cryptographic Service Providers (CPS) unter Java, welcher durch Einbettung von OpenSC Funktionen realisiert wird • Minimale Funktionen des CSP: o Abrufen von auf der Smartcard gespeicherten Zertifikaten o RSA Signatur eines MD5 oder SHA‐1 Hashwertes auf der Smartcard • Erstellen einer kleinen Java Demo‐Applikation, welche die realisierten JCE Funk‐ tionen aufruft Jan Keller Carla Schaffner VI 24.10.2003 Java Smartcard Unterstützung unter Linux Vorspann Zusammenfassung Die vorliegende Diplomarbeit befasst sich mit der Verwendung von Smartcards im Zu‐ sammenhang mit dem populären und häufig verwendeten RSA Public Key Algorithmus, genauer gesagt mit dessen Funktionen digitale Signatur und Verschlüsselung. Sicherheitstechnisch gesehen sind Smartcards durch die Tatsache, dass der auf der Karte gespeicherte private Schlüssel die Smartcard nicht mehr verlassen kann, ein optimales Speichermedium für schützenswerte Objekte. Die Hauptaufgabe dieser Diplomarbeit bestand darin, auf der Linux‐Plattform ein Cryp‐ tographic Service Provider (CSP) für Java zu realisieren. Dessen Hauptfunktion besteht darin, durch die Signatur von Daten die Authentizität des Signierenden und die Integrität der Daten sicherzustellen. Der Provider konnte nicht in reinem Java entwickelt werden, da das verwendete PKCS#11 API für den Zugriff auf die Smartcard in C geschrieben ist. Um die Koppelung von C und Java zu realisieren, wurde das JNI (Java Native Interface) von SUN verwendet. Dennoch musste ein wesentlicher Teil in C kodiert werden, um das PKCS#11 API voll auszunutzen. Um zu gewährleisten, dass der KelschaJLin Provider von jeglichen Java Applikationen verwendet werden kann, wurde dieser nach dem JCA / JCE (Java Cryptography Archi‐ tecture / Extension) implementiert. Diese Schnittstellen geben vor, wie ein Provider reali‐ siert werden muss, um dessen Funktionen verwenden zu können. Für die C Program‐ miersprache standen uns die Bibliotheken von OpenSC und PKCS#11 zur Verfügung. Der in dieser praktischen Arbeit erstellte KelschaJLin Provider Version 1.0 wurde bislang mit zwei Services ausgestattet: Zum Einen ist es möglich von beliebigen Daten einen MD5 oder SHA‐1 Hash zu generieren, welcher anschliessend auf der Smartcard signiert wird und zum Andern können alle auf der Smartcard gespeicherten Zertifikate abgerufen wer‐ den. Unter Verwendung eines OpenSC‐Releases ab 1. Oktober 2003 wäre es, gemäss Angaben der Entwickler, auch möglich den Provider KelschaJLin um die Funktion des Entschlüs‐ selns zu erweitern. Datum: Jan Keller Carla Schaffner Jan Keller Carla Schaffner VII 24.10.2003 Java Smartcard Unterstützung unter Linux Vorspann Abstract This diploma paper deals with the widespread RSA Public Key Algorithm and its func‐ tions sign and encrypt in conjunction with keys stored on a smart card. Because of the fact that a private key ‐ once stored on a smart card ‐ can never be retrieved or even read, smart cards are a very secure place to save secret objects. The essential part of this diploma thesis was to develop a Cryptographic Service Provider (CSP) for Java based on the Linux operating system. This provider offers functions to sign data whereby the authenticity of the sender and the integrity of the data are guaranteed. Due to the fact that the used PKCS#11 API provided by the OpenSC workgroup is written in C, it was not possible to develop the provider in pure Java. Therefore Sun’s JNI (Java Native Interface) was used to link the pieces of C code with Java. To ensure that the pro‐ vider can be properly used by any application it is built according to the Java Cryptogra‐ phy Architecture / Extension (JCA / JCE). These interfaces describe the structure of the provider and designate how the functions have to be called. The actual version 1.0 of the KelschaJLin provider supports two features: • Generation of a MD5 or SHA‐1 hash that gets signed on the smart card. • Retrieval of the certificates stored on the smart card Equipped with an OpenSC library released after October 1 2003, it should be possible – according to the developers – to supply the provider KelschaJLin with an decryption func‐ tion. Jan Keller Carla Schaffner VIII 24.10.2003 Java Smartcard Unterstützung unter Linux 1. Einleitung Einleitung Der vorliegende Bericht beschreibt die Arbeiten, die während 7 Wochen für die Realisie‐ rung des Cryptographic Service Provider gemacht worden sind. Der Bericht dient dazu, den Stand der Arbeit zu dokumentieren und die Voraussetzung zu schaffen, dass die Ar‐ beit zu einem späteren Zeitpunkt fortgesetzt werden kann. Der Bericht ist in folgende Bereiche aufgeteilt: In den Kapiteln 2 und 3 werden die Planung und die Anforderungen des Projektes be‐ schrieben. In den Kapiteln 4 und 5 werden die technischen Grundlagen der verwendeten Methoden und Lösungen geschaffen und eine Problemanalyse erstellt. Die Kapitel 6 und 7 beschreiben die angewendeten Verfahren, Lösungswege und Hilfs‐ mittel, die für das Lösen der Aufgaben verwendet wurden. Der letzte Teil des Berichts, die Kapitel 8 ‐ 11 soll einen Überblick über das Endprodukt und dessen Verwendung und Erweiterung geben. In diesen Kapiteln werden auch die Testresultate beschrieben, die das Erfüllen der Aufgaben bestätigen. Im Anhang werden die wichtigsten Informationen zu den gelösten Aufgaben und die Informationsquellen in den Bericht aufgenommen. Planung / Vorgehen (Seite 2 ‐ 4) • • Projektplan Pflichtenheft • • Grundlagen Problemanalyse • • Lösungskonzept Komponenten • • • • Test Probleme Verwendung Schlusswort • • • • Glossar Source Code Quellenverweise Anleitungen Grundlagen (Seite 5 ‐ 28) Lösung (Seite 29 ‐ 53) Endprodukt (Seite 55 ‐ 82) Anhang (Seite 83 ‐104) Jan Keller Carla Schaffner 1 24.10.2003 Java Smartcard Unterstützung unter Linux 2. Projektplanung 2 24.10.2003 Projektplanung 2.1. Netzplan Jan Keller Carla Schaffner Parallel zu den jeweiligen Tasks wurde an der Dokumentation gearbeitet, damit sie in den letzten Wochen nur noch zusammen‐ gestellt und angepasst werden musste. Java Smartcard Unterstützung unter Linux 2.2. Projektablaufplan Jan Keller Carla Schaffner Projektplanung 3 24.10.2003 Java Smartcard Unterstützung unter Linux 3. Pflichtenheft Pflichtenheft 3.1. Funktionale Anforderungen [1] Aufgaben des Providers Es muss möglich sein, mit diesem Provider alle auf der Smartcard gespeicherten Zerti‐ fikate abzurufen. Zudem muss er die Funktionalität unterstützen, einen SHA‐1 oder MD5 Hashwert mit dem auf der Karte gespeicherten Private Key zu signieren. [2] Einbindung des Providers Der Provider soll mittels „Plug and Play“ in die eigene Java Applikation eingesetzt werden können. Um dies zu gewährleisten muss der Provider nach JCE (Java Cryp‐ tographic Extension) implementiert werden. [3] Einbindung des PKCS#11 API Um auf die Smartcard zuzugreifen, soll das bestehende PKCS#11 API benutzt werden. Die C‐Funktionsaufrufe von OpenSC sollen dann in ein Java Native Interface (JNI) ein‐ gebettet werden, um mit dem Provider darauf zugreifen zu können. 3.2. Nicht‐funktionale Anforderungen [1] Plattformen Dieser Provider wird für die Linux Plattform geschrieben. Das J2SDK1.4.1 muss instal‐ liert und lauffähig sein. Zudem müssen die OpenSC Tools vom OpenSC Projekt und der Treiber für PC/SC Reader Reflex 72v2 von Schlumberger installiert sein. [2] Hardware Der für diese Arbeit verwendete Smartcard Reader ist der Schlumberger Reflex 72v2., sowie die Crytoflex Smartcard von Schlumberger. Jan Keller Carla Schaffner 4 24.10.2003 Java Smartcard Unterstützung unter Linux 4. Grundlagen Grundlagen 4.1. Hashfunktion Eine Einweg‐Hashfunktion dient in erster Linie dazu, eine Menge von Daten auf eine bestimmte Länge zu komprimieren. Das Ergebnis dieser Funktion ist der so genannte Hash oder Fingerprint. Dieser Hash ist eine eindeutige Prüfsumme einer Datei oder ei‐ nes Datensatzes. Der Hashwert sollte von jedem einzelnen Bit der Datei abhängen, damit bei kleinster Änderung der Datei, der Hashwert grundlegend verändert wird. Es ist wichtig, dass eine Hashfunktion schnell und effizient arbeitet, da es auch mög‐ lich sein muss, gigabytegrosse Dateien einer Hashfunktion zu übergeben. Zudem dür‐ fen zwei verschiedene Dateien nie denselben Hash ergeben. Die gängigsten Hashfunktionen sind MD5 (Message Digest 5) und SHA‐1 (Secure Hash Algoritm 1). In dieser Arbeit wird nicht näher auf die genaue Erstellung eines Hash eingegangen. 1 4.2. Zertifikate Ein digitales Zertifikat ist mit einem Reisepass vergleichbar. Es dient ebenfalls dem Identitätsnachweis. Genauer gesagt bestätigt es, dass ein bestimmter Public Key (der im Zertifikat enthalten ist) auch derjenigen Person gehört, die sich als dessen Eigentü‐ mer ausgibt. Wie der Reisepass auch, wird das Zertifikat von einen vertrauenswürdi‐ gen Stelle, einer so genannten Zertifizierungsstelle (CA) wie zum Beispiel VeriSign, ausgestellt. Im Gegensatz zum Reisepass gibt es jedoch keine staatliche Zertifizie‐ rungsstelle. Anwendungen von Zertifikaten sind ‐ um einige Beispiele zu nennen ‐ elektronische Unterschriften, sichere E‐Mails und Authentisierung bei Client‐Server Anwendungen. Der am weitesten verbreitete Standard für digitale Zertifikate ist er X.509 Standard. Ein digitales Zertifikat ist eine codierte Datei, welche folgende Informationen enthalten muss: • • • • • Name des Zertifizierungsobjektes Name der Ausgabestelle (z.B. VeriSign) Digitale Signatur der Zertifizierungsstelle (MD5 oder SHA‐1) Public Key (z.B. RSA 1024 Bit Schlüssel) Gültigkeitsdauer Für weitere Informationen siehe RFC 1321 (MD5) und FIPS PUBS (SHA1) 1 Jan Keller Carla Schaffner 5 24.10.2003 Java Smartcard Unterstützung unter Linux 4.3. Grundlagen Kryptographie Kryptographie ist die Kunst und Wissenschaft, Daten so zu verändern, dass sie sicher sind vor unberechtigtem Lesen oder Verändern. Es gibt verschiedene Algorithmen in der Kryptographie. In dieser Arbeit wird auf die Public Key Kryptographie (asymmet‐ rische Kryptographie) eingegangen. Bei den asymmetrischen Algorithmen, denen das Prinzip vom öffentlichen und priva‐ ten Schlüssel (Public / Private Key) zugrunde liegt, unterscheiden sich Chiffrier‐ und Dechiffrierschlüssel. Es ist schwierig, beziehungsweise bei ausreichender Schlüssellän‐ ge praktisch unmöglich, den Dechiffrierschlüssel aus dem Chiffrierschlüssel zu be‐ rechnen.2 Der öffentliche Schlüssel (Public Key) ist, wie der Name schon sagt, öffentlich bekannt; mit ihm kann jeder eine Nachricht verschlüsseln, aber nur die Person, die im Besitz des privaten Schlüssels (Private Key) ist, kann die Nachricht entschlüsseln und lesen. Wird das Verfahren entgegengesetzt angewendet, so nennt man dies Signieren. Einer der bekanntesten Public Key‐Algorithmen ist RSA. Die Public Key Kryptographie basiert auf dem Prinzip der Primfaktorenzerlegung. Um ein Schlüsselpaar zu berechnen sind folgende Schritte notwendig: Es werden zwei grosse (1024 Bit) Primzahlen p und q zufällig gewählt. Aus diesen beiden Primzahlen wird nun das Produkt berechnet p * q = n Ein öffentlicher Exponent e muss gewählt werden, wobei gilt, dass e < (p‐1)(q‐1) und die e, (p‐1) und (q‐1) keine gemeinsamen Primfaktoren haben. Nun kann der private Exponent berechnet werden: d = e ‐1 mod (p‐1)(‐1) nach dem Euklischen Algorithmus kann die Formel folgendermassen umgeformt werden: d * e mod (p‐1)*(q‐1) = 1 Der Private Key besteht aus dem privaten Exponent d und dem Modulus n. Der Public Key besteht aus dem öffentlichen Exponent e und dem Modulus n. Die Primfaktoren p und q werden nach der Schlüsselerzeugung nicht mehr gebraucht. Aus diesem Grund sollten sie sofort nach deren Verwendung gelöscht werden, damit die Berechnung des Private Key mit Hilfe diesen Faktoren nicht mehr möglich ist. Soll nun ein Plaintext x verschlüsselt werden, wird dies mit der Funktion y = xe mod n gemacht. Die Entschlüsselung des Ciphertext y jedoch wird dann mit der Funktion x = yd mod n berechnet. http://mitglied.lycos.de/cthoeing/crypto/minidict.htm 2 Jan Keller Carla Schaffner 6 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Einfaches Rechenbeispiel: 1. p= 3, q = 17 2. n = p * q = 51 3. (p‐1)*(q‐1) = 2 * 16 = 2 * 2 * 2 * 2 * 2 = 32 (öffentlicher Exponent darf keine 2 enthal‐ ten) 4. mögliche Kombinationen von öffentlichen und privaten Exponenten: e d e * d e * d mod 32 3 11 33 1 5 13 65 1 7 23 161 1 9 25 225 1 11 3 33 1 13 5 65 1 15 15 225 1 17 17 289 1 19 27 513 1 21 29 609 1 23 7 161 1 25 9 225 1 27 19 513 1 29 21 609 1 31 31 961 1 Mit einem RSA Schlüsselpaar, bestehend aus Private und Public Key, können ver‐ schiedene kryptografische Operationen ausgeführt werden. In den nächsten Seiten werden folgende Operationen genauer erklärt. • Verschlüsseln • Entschlüsseln • Signieren • Verifizieren Jan Keller Carla Schaffner 7 24.10.2003 Java Smartcard Unterstützung unter Linux 4.3.1. Grundlagen Verschlüsseln (Encrypt) Sensible Daten, die versendet werden und nur vom Empfänger gelesen werden dür‐ fen, können mit dem Public Key dieser Person verschlüsselt werden. Durch diese Verschlüsselung können Nachrichten vor unbefugtem Lesen geschützt werden. Plaintext, der nur von einer autorisierten Person gelesen Dies ist der Plaintext, werden darf. der verschlüsselt werden soll. Encryption with Die Daten werden mit dem Public Key des Empfängers Public Key verschlüsselt. vbnzusianuezthwolmynz wpnchndakidhnekiadfkid Der Ciphertext3 wird nun über das öffentliche, unsichere nfkdosinkdosjdkkkad Netz (z.B. Internet) übertragen. Abbildung 1: Vorgang verschlüsseln verschlüsselter Text, Schlüsseltext 3 Jan Keller Carla Schaffner 8 24.10.2003 Java Smartcard Unterstützung unter Linux 4.3.2. Grundlagen Entschlüsseln (Decrypt) Daten, die für eine bestimmte Person verschlüsselt wurden, können nicht eingese‐ hen werden. Deshalb müssen sie zuerst mit dem Private Key des Betreffenden ent‐ schlüsselt werden. vbnzusianuezthwolmynz Die erhaltene Nachricht ist verschlüsselt und kann so wpnchndakidhnekiadfkid nfkdosinkdosjdkkkad nicht entziffert werden. Decryption with Mit dem eigenen Private Key können nun die verschlüs‐ Private Key selten Daten entschlüsselt werden. Ist die Nachricht mit dem eigenen Public Key verschlüs‐ Dies ist der Plaintext, der verschlüsselt werden selt worden, kann nach der Entschlüsselung die Nach‐ soll. richt in Plaintext gelesen werden. Abbildung 2: Vorgang entschlüsseln 4.3.3. Signieren (Sign) Täglich wird eine Unmenge von Daten über einen unsicheren Kanal (z.B. das Inter‐ net) versendet. Soll nun die Integrität der Daten und die Authentizität des Senders sichergestellt werden, kann die digitale Signatur benutzt werden. Dies ist die Nachricht, Dieser Text soll signiert werden. die signiert werden soll. Zuerst wird über das ganze Dokument ein Hash gebil‐ det. Beispielsweise können die Hash‐Algorithmen MD5 Hash Function oder SHA‐1 verwendet werden. 1001011000111001 Der Hashwert ist je nach Algorithmus 128 (MD5) oder 160 (SHA‐1) Bit lang. Encryption with Nun wird der Hashwert mit dem Private Key verschlüs‐ Private Key selt. Signature Daraus erfolgt die 1024 Bit lange Signatur. Abbildung 3: Vorgang signieren Jan Keller Carla Schaffner 9 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Der Sender schickt die Signatur und den unverschlüsselten Text dem Empfänger. Ist dieser im Besitz des Public Keys des Senders, kann er die Signatur verifizieren. 4.3.4. Verifizieren (Verify) Um eine signierte Nachricht zu verifizieren, muss der Empfänger im Besitz des Pub‐ lic Keys des Senders sein. Meist wird bei signierten Nachrichten das Zertifikat, das zugleich auch den Public Key enthält, mit gesendet. Falls dies nicht der Fall ist, muss das Zertifikat anderswo (z.B von einem LDAP‐Server) herunter geladen wer‐ den. Vom Sender der Nachricht bekommt man sowohl die unverschlüsselte Nach‐ richt, als auch die 1024 Bit lange Signatur. Die empfangene Nachricht, die auf Integrität und Dies ist die Nachricht, Authentizität überprüft werden soll. die signiert werden soll. Auch der Empfänger bildet einen Hashwert über das ganze Dokument. Empfänger und Sender müssen Hash Function denselben Algorithmus gebrauchen. 1001011000111001 Stimmen die beiden Hashwerte überein, so ist die Integrität der Daten und Authentizität des Senders 1001011000111001 sichergestellt. Diese Signatur wird mit dem Public Key des Senders Decryption with entschlüsselt. Diese Entschlüsselung ergibt einen Hash‐ Public Key wert, der mit dem erstellten Hash übereinstimmen muss. Signature Die empfangene Signatur. Abbildung 4: Vorgang verifizieren Jan Keller Carla Schaffner 10 24.10.2003 Java Smartcard Unterstützung unter Linux 4.4. 4.4.1. Grundlagen Smartcards Was sind Smartcards Die Bezeichnung „intelligente Karte“ beschreibt einen Datenträger im Kreditkarten‐ format mit unterschiedlichen Fähigkeiten. Die Smartcard enthält einen eingebette‐ ten Chip, der Daten verarbeitet und ‐ durch eine Reihe von Sicherheitsmerkmalen geschützt ‐ speichert. Im Wesentlichen werden drei verschieden Arten von Smart‐ cards unterschieden: Speicherkarten Diese Karte kann nur Daten speichern und enthält keinen eigenen Prozessor. Daher benötigt sie einen Fremdprozessor ausserhalb der Karte um Daten zu verarbeiten. Dieser Kartentyp bietet das geringste Sicherheitsniveau. Mikroprozessorkarten Eine Mikroprozessorkarte hat ihren eigenen Prozessor mit Betriebssystem und kann so selbständig Daten verarbeiten. Besitzt eine Karte zusätzlich einen numerischen Koprozessor, wird sie Kryptokarte genannt und wird für kryptografische Anwen‐ dungen benutzt. Für die Kommunikation mit der Umwelt, muss die Karte in einen Kartenleser ein‐ geführt werden. Bei dieser Art von Karte ist der Chip von aussen sichtbar. Kontaktlose Karte Diese Karten kommunizieren ‐ innerhalb eines bestimmten Mindestabstandes zu ei‐ ner Antenne ‐ über ein Radiosignal mit dem Computer. Der Chip und die Antennen sind von Aussen meist nicht sichtbar. Heute sind sowohl kontaktlose Speicherkar‐ ten als auch kontaktlose Mikroprozessorkarten erhältlich. 4.4.2. Einsatzgebiet der Smartcards Die Anwendungsmöglichkeiten der Chipkarten sind äusserst vielseitig und nehmen dank der wachsenden Rechenleistung und Speicherkapazität stetig zu. Hier wird nur eine kleine Übersicht über einigen Anwendungen aufgeführt. Die Smartcards wurden durch den Gebrauch als öffentliche Telefonkarten schnell bekannt. In der Zwischenzeit werden diese Karten auch als Krankenversicherungs‐ karten, SIM‐Karten für Mobiltelefone, EC‐Karten, und wie in unserer Arbeit für di‐ Jan Keller Carla Schaffner 11 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen gitale Signaturen eingesetzt. Im Ausland werden Smartcards sogar für Mautsyste‐ me4 genutzt.5 4.4.3. Filesystem der Smartcards Das ISO 7816‐4 Filesystem der Chipkarte besteht aus 3 verschiedenen Filetypen: Elementary Files (EF) EF’s dienen der eigentlichen Datenablage. In ihnen werden Namen, Daten oder Se‐ riennummern gespeichert. Es gibt vier verschiedene Arten von Elementary Files: • Transparent EF Dienen vor allem der Speicherung von Objekten wie Schlüssel, Zertifikate, usw. Ein Transparent EF ist ein Speicherobjekt ohne interne Struktur (daher transparent). Beim Zugriff werden der Offset und die Anzahl zu bearbeiten‐ der Bytes angegeben. • Fixed‐length linear EF Das Speicherobjekt ist aufgeteilt in verschiedene Bereiche, so genannte Re‐ cords. Jeder Record wird durch eine eindeutige Nummer angesprochen, die er bei der Erstellung zugeteilt bekommt. Wie der Name schon sagt sind die fixed‐length linear EF in Records gleicher Grösse aufgeteilt. Die Grösse der Records beträgt 0 bis 255 Bytes, die maximale Anzahl Records liegt bei 255. • Variable‐length linear EF Im Gegensatz zu den fixed‐length linear EF können in den variable‐length linear EF Records verschiedener Grössen erstellt werden. Auch hier beträgt die Grösse 0 bis 255 Bytes und die Anzahl möglicher Records 255. • Cyclic EF Wie bei den fixed‐length linear EF, werden cyclic EF in 0 bis 255 Records gleicher Grösse unterteilt. Die Adressierung erfolgt jedoch in einem Ring, in dem der aktuelle Record immer den Index 1 besitzt. Wurde der letzte Record geschrieben, springt der Zeiger wieder auf den ersten, der dann überschrie‐ ben wird. Cyclic EF’s werden vor allem dazu gebraucht, den Verlauf der letzten Transaktionen zu speichern. Systeme für Strassensteuer Weitere Informationen sind im Buch „Handbuch der Chipkarten“ von Wolfgang Rankel und Wolfgang Effing zu finden. 4 5 Jan Keller Carla Schaffner 12 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Dedicated Files (DF) Ein DF ist ein Unterverzeichnis im Filesystem und kann weitere DF’s oder EF’s ent‐ halten. Existiert ein key file (z.B. CHV) im Verzeichnis, wird dessen PIN für die Zugriffsrechte verwendet. Ist dies nicht der Fall, wird im nächst höheren Verzeich‐ nis gesucht bis eins gefunden wird. Das heisst ein key file gilt pfadabwärts so lange bis ein anderes die Zugriffskontrolle übernimmt. Master File (MF) Das MF ist im Grunde genommen ein normales DF mit der Bezeichnung 3F00, das beim Hochfahren des Kartenprozessors selektiert wird. Es ist das Wurzelverzeichnis des Filesystems. Eine neue oder mit dem cryptoflex‐eraser gelöschte Karte, weist folgende Filestruk‐ tur auf: 3F00 0011 38 0002 8 0000 23 Abbildung 5: Filestruktur cryptoflex‐eraser Unter dem Wurzelverzeichnis MF (3F00) werden noch ein external key file (0011) , ein serial number file (0002) und ein key file (0000) angelegt. Nach der Erstellung der PKCS#15‐Struktur mit dem pkcs15‐init Tool, sieht das Da‐ teisystem der Karte folgendermassen aus: wEF DF 3F00 0011 38 Name Grösse 0002 8 0000 23 4401 256 5015 6196 2F00 128 5031 256 5032 42 Abbildung 6: PKCS#15 Filestruktur Jan Keller Carla Schaffner 13 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Eine detaillierte Beschreibung der einzelnen Files ist in der Tabelle auf Seite 16 zu finden. Wird noch ein Zertifikat mit dazugehörendem Private Key auf die Karte geladen, finden wir folgende Dateistruktur vor: 3F00 0011 38 4401 256 5031 256 5032 42 0002 8 5501 836 0000 23 0000 23 4404 512 0012 326 5015 4816 4B01 168 2F00 128 4402 256 5201 140 4403 256 1012 330 Abbildung 7: Karte mit Zertifikat und Private Key Die beiden grünen Dateien gehören zum Zertifikat, die Roten beinhalten die Private / Public Keys beziehungsweise den PIN / PUK dazu. PKCS#1 erstellt standardmässig im Verzeichnis 5015 ein Public Key File 5201 mit dazugehörendem Zeiger 4403. Dadurch ist der Public Key zweimal auf der Karte vorhanden. Einmal im File 5201 (PKCS#1) und ein weiteres Mal im Cryptoflex‐ spezifischen Verzeichnis 4B01 im File 1012. Da erstens der Public Key nicht besonders schützenswert ist und er zweitens auch im Zertifikat enthalten ist, sind die Files 5201 und 1012 eher belanglos. Wird ein weiteres Zertifikat inklusive Private Key hinzugefügt, erstellt PKCS#15 ein weiteres Zertifikatfile (5502), aktualisiert den Zeiger 4404 und erstellt ein neues Ver‐ zeichnis (4B02) mit derselben Filestruktur für den zweiten Private Key. Werden die Beziehungen im Dateisystem grafisch dargestellt, wird deutlich wo die wirklichen Daten liegen: Jan Keller Carla Schaffner 14 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen 3F00 4401 256 5031 256 0011 38 0002 8 0000 23 5015 4816 5032 42 5501 836 4404 512 4B01 168 0000 23 0012 326 1012 330 2F00 128 4402 256 5201 140 4403 256 Abbildung 8: Zeiger‐ und Datenfiles Die roten Dateien beinhalten die Schlüssel, die blauen Regeln den Zugriff (PIN/PUK), in den grünen Dateien ist das Zertifikat gespeichert und in den orangen sonstige Informationen, wie Seriennummer und Hersteller der Karte. Abgesehen von den Cryptoflex‐proprietären Files unterhalb 4B01 sind alle Dateien in ASN.1 kodiert. Jan Keller Carla Schaffner 15 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Beschreibung der Files: 3F00 Master file / root directory 0011 External key file Manufacturing‐ und Transportkey. Karte wird gesperrt wenn gelöscht. 0002 Serial Number File 00 01 81 0B FF FF 01 00. Karte wird unbrauchbar wenn gelöscht. 0000 CHV key file Beinhaltet PIN und PUK des aktuellen Verzeichnisses 5015 Verzeichnis 2F00 DIR Zeiger auf eine oder mehrere PKCS#15 Verzeichnisse (hier 5015) 4401 DODF (Data Object Directory File) Zeiger auf Verzeichnis mit den Private Keys. 3F00/5015/4B01 5031 ODF (Object Directory File) Zeigt auf die Zeiger, die auf die verschiedenen PKCS#15 Objekte zeigen. (PrKey, PubKey, Cert, …) 3F00/5015/4402, 4403 und 4404. 5032 TokInf „OpenSC Project / OpenSC Card“ 5501 Cert x Zertifikat in ASN1 4404 CDF (Certificate Directory File) Zeiger auf Zertifikat. 3F00/5015/5501 4B01 Verzeichnis 4402 PrKDF (Private Key Directory File) Zeiger auf einen oder mehrere Private Keys. 3F00/5015/4B01/0012. 5201 Public Key (PKCS#1) 4403 PuKDF (Public Key Directory File) Zeiger auf Public Key. 3F00/5015/5201 0012 Private Key 1012 Public Key (Cryptoflex) Tabelle 1: Beschreibung der Dateien Jan Keller Carla Schaffner 16 24.10.2003 Java Smartcard Unterstützung unter Linux 4.5. Grundlagen PC / SC Die PC/SC (Personal Computer / Smartcard) Workgroup, bestehend aus den Core Members Apple, Gemplus, Infineon, Ingenico, Microsoft, Philips, Schlumberger und Toshiba, setzte sich zum Ziel, eine hersteller‐ und plattformunabhängige Spezifikation zu entwickeln und somit den Einsatz von Smartcards im PC‐Bereich zu fördern. Unter Linux ist das PC/SC API als 3‐Tier‐Architektur realisiert und stellt somit eine Unabhängigkeit zwischen der Applikation und den Smartcard‐Readern her. Das heisst, die Anwendung kommuniziert mit der Middleware PC/SC, die dann wiederum einen oder mehrere Reader ansteuert. Der PC/SC Standard verlangt, dass die Kommunikation auf der untersten Ebene nach ISO 7816 verläuft. Die Architektur besteht aus folgenden Komponenten: ICC Aware Application 1 Tier ServiceProviders Providers Service 2 Tier ICC Resource Manager IFD Handler IFD Handler IFD Handler PS/2 RS-232 PC Card IFD IFD IFD ICC ICC ICC 3 Tier Abbildung 9: PC/SC‐Architektur Jan Keller Carla Schaffner 17 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen ICC Aware Application Beliebiges Programm, das die Funktionen einer SmartCard nutzen möchte. Service Providers Der Service Provider ist dafür verantwortlich, dass die Funktionen einer SmartCard den höher gelegenen Applikationen transparent zur Verfügung stehen. Das heisst, die Applikation kann unabhängig von Karte, Hardware oder Betriebssystem darauf zugreifen und muss auch die interne Struktur der Karte nicht kennen. Laut Spezifikation besteht der Service Provider aus zwei unabhängigen Komponenten: dem ICC Service Provider und dem Cryptographic Service Provider. Obwohl das Gan‐ ze normalerweise als eine Komponente anzutreffen ist, macht die Unterteilung wegen Import‐ / Exportbeschränkungen der verschiedenen Länder Sinn. ICC Service Provider Der ICC Service Provider stellt höher gelegenen Applikationen SmartCard‐spezifische Zugriffsfunktionen, wie Dateizugriff oder Authentifizierung zur Verfügung. Bevor ein Service Provider mit der SmartCard kommunizieren kann, muss er sich beim ICC Resource Manager „anmelden“. Bei diesem Vorgang werden dem Service Provi‐ der Informationen zur Karte mitgeteilt, die er dann zu dessen Ansteuerung braucht. Cryptographic Service Provider Der Cryptographic Service Provider stellt höher gelegenen Applikationen SmartCard‐ spezifische, kryptografische Funktionen zur Verfügung. Dazu gehören: • Schlüsselgenerierung • Schlüsselmanagement • Digitale Signaturen • Hashing • Verschlüsselungsdienste Sollte eine oder mehrere dieser Funktionen Import‐ oder Exportbeschränkungen unter‐ liegen, wird der Service Provider ohne Cryptographic Service Provider ausgeliefert und die SmartCard‐Applikation läuft bis auf diese Funktionen einwandfrei. ICC Resource Manager Als eine der wichtigsten Komponenten in der PC/SC Architektur ist der ICC Resource Manager verantwortlich für die Verwaltung der ICC‐Ressourcen und den gesicherten Zugriff auf die SmartCard. Diese System‐Level‐Komponente wird meistens vom Be‐ triebssystemlieferant bereitgestellt und darf pro System nur einmal installiert sein. Kommuniziert wird über RPC. Jan Keller Carla Schaffner 18 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Folgende Probleme behandelt der ICC Resource Manager im Zusammenhang mit dem Zugriff auf mehrere IFD’s und ICC’s: • Bereitstellen von Informationen über installierte IFD’s und Smartcardtypen und deren unterstützte Funktionen. Überwachen des Einsteckens und Entfernen von ICCs für das Anbieten von Informationen über betriebsbereite Smartcards. • Regelung des Zugriffs auf die ICCs unter mehreren Applikationen. • Definition von Transaktionsprimitiven (transaction primitives). Da Smartcards single‐threaded devices sind, müssen für eine Funktion zum Teil mehrere Be‐ fehle ausgeführt werden. Transaktionsprimitiven stellen sicher, dass im Mehr‐ programmbetrieb diese Befehlsfolgen auch atomar ablaufen und nicht unter‐ brochen werden. IFD Handler Der IFD Handler wird vom Hersteller des Readers mitgeliefert und ist der eigentliche Treiber für den IFD. Er ermöglicht den höher liegenden Komponenten den Zugriff auf den Reader, unabhängig von Hardware und Eigenschaften der Karte. Vom IFD Handler bis hinunter zur Smartcard erfolgt die Kommunikation gemäss der ISO 7816‐3 Norm. IFD Das Interface Device (oder auch Smartcard Reader) ist die physikalische Verbindung zwischen Chipkarte und Computer. Über mehrere Kontakte ist die Smartcard mit dem Reader verbunden und wird somit mit Strom, Clock und Datenleitung versorgt. Als physikalischer Anschluss dient PS/2, RS‐232, PCMCIA oder USB. IFD sowie auch ICC müss en den ISO‐Normen 7816‐1,2,3 entsprechen. ICC Integrated Chip Card. Smartcard oder Chipkarte. Jan Keller Carla Schaffner 19 24.10.2003 Java Smartcard Unterstützung unter Linux 4.6. Grundlagen Padding Im Falle einer RSA‐Signatur ist ein zu signierender Datenblock 128 oder 160 Bit und die resultierende Signatur 1024 Bit lang. Padding beschreibt die Methode, wie die restlichen 896 beziehungsweise 864 Bit „auf‐ gefüllt“ werden und hat zum Zweck, Zufälligkeit in die Signatur eines Textes zu brin‐ gen. Zufälligkeit, damit der Signaturvorgang eines Textes durch verschiedene Anwen‐ dungen auch verschiedene Signaturen hervorbringt und sie somit vor „Chosen Cipher‐ text“‐Attacken zu schützen. 4.6.1. PKCS#1 v1.5 Padding PKCS#1 v1.5 Padding ist zwar noch im RSA Standard enthalten, jedoch nur aus Kompatibilitätsgründen mit älteren Applikationen. Für neue Anwendungen wird dringend der Gebrauch von OAEP oder PSS empfohlen. Beim PKCS#1 v1.5 Padding wird der zu füllende Platz (am Beispiel SHA1: 1024 Bit Signatur minus 160 Bit Hash gleich 864 Bit Padding) vorwiegend mit zufälligen non‐zero‐Bytes aufgefüllt. Um die eigentlichen Daten vom Padding unterscheiden zu können, werden zu Beginn und am Ende des Padding ein 0‐Byte eingefügt, Nach dem 0‐Byte am Anfang wird zudem noch ein „block type“ byte eingefügt, das den Typ der RSA‐Operation definiert. Bei Ver‐ / Entschlüsselungsoperationen bei‐ spielsweise ist es 0x02, bei Signatur‐ / Verifikationsoperationen ist es 0x01. plaintext Hashing ©J.åì±.š.L.só/é.I 20 Byte SHA1 ©J.åì±.š.L.só/é.I 20 Byte Hash + 108 Byte Padding Padding 0 2 random 0 Signing !òCÉÏ' æ6Œƒà¡"É8Á[qå-+¿Ÿ[æø´¿b / ü4 ÈF"`PajļÇÁ "ó# r†‰" 128 Byte Signature Abbildung 10: Paddingvorgang bei PKCS#1 v1.5 Jan Keller Carla Schaffner 20 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Nachdem 1998 die so genannte „Million Message Attack“ von Bleichenbacher be‐ kannt wurde, bei der in einer SSL‐Sitzung durch die Übermittlung von sehr vielen, zufällig konstruierten Geheimtexten mit Hilfe der Server‐Antworten auf den Schlüs‐ sel geschlossen werden konnte, brachte RSA eine verbesserte Version (2.0) des Stan‐ dards heraus. Wie sich jedoch herausstellte, war die neue Version sogar noch anfäl‐ liger auf eine leicht abgeänderte Attacke. Waren bei Version 1.5 noch circa eine Mil‐ lion modifizierter Geheimtexte nötig, reichten bei Version 2.0 gerade noch einige Tausend. Digital signierte Mails oder Texte sind von dieser Attacke nicht betroffen. Da das Opfer mindestens einige Tausend verschlüsselte Meldungen bekommt und auswer‐ ten muss, kommt dafür nur eine Maschine in Frage. Deshalb sollte die Verwendung vom PKCS#11 v1.5 Paddingverfahren bei solchen digitalen Signaturen problemlos sein. 4.6.2. RSA OAEP RSA OAEP (Optimal Asymmetric Encryption Padding), 1994 von Bellare und Ro‐ gaway entwickelt und seit der Version 2.0 im RSA‐Standard enthalten, ist eine der sichersten Methoden, um Daten für die RSA‐Verschlüsselung zu kodieren. Im Folgenden ist der –im Vergleich zum PKCS#1 v1.5 Padding wesentlich kompli‐ ziertere – Ablauf skizziert. Gegeben sind: • mHash Hashwert des Klartextes • mLen Länge des Klartextes • P Parameter • pHash Hash der Parameter • PS Padding String • emLen Länge der Signatur • Hash Hashfunktion • hLen Länge des Hash • MGF Mask Generation Function 1. wähle einen zufälligen String seed 2. stelle einen String PS (Padding String) zusammen, bestehend aus emLen, mLen, hLen und einem 0‐Byte 3. berechne pHash = Hash(P) 4. Data Block DB = pHash + PS + M 5. dbMask = MGF(seed,Len) 6. maskedDB = dbMask XOR DB 7. seedMask = MGF(maskedDB, Len) Jan Keller Carla Schaffner 21 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen 8. maskedSeed = seed XOR seedMask 9. EM = maskedSeed + masked DB 10. der padded hash wird nun mit dem Private Key signiert seed mHash PS pHash Data Block MGF maskedDB MGF maskedSeed padded hash Abbildung 11: Paddingvorgang bei OAEP OAEP RSA‐verschlüsselt gilt als beweisbar sicher. Genauer gesagt, wenn die Hash‐ funktionen im MGF wirklich zufällig sind, dann muss für die Entschlüsselung der Meldung RSA geknackt werden. Bis heute wurde in OAEP noch keine Schwachstel‐ le entdeckt. Da OpenSC 0.8.0 OAEP leider noch nicht unterstützt, wird in der vorliegenden Ar‐ beit das „normale“ PKCS#1 v1.5 Paddingverfahren verwendet. 4.6.3. RSA PSS RSA‐PSS (Probabilistic Signature Scheme) ist seit Version 2.1 im PKCS#1 Standard enthalten und entspricht vor allem im Bereich der Sicherheit den heutigen Anforde‐ rungen. Zwar wird momentan noch das PKCS#1 v1.5 Signaturschema als „state of the art“ angesehen, RSA empfiehlt jedoch einen langsamen aber sicheren Übergang zu PSS. Jan Keller Carla Schaffner 22 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen Ein PSS‐Paddingvorgang geht wie folgt vor sich: Gegeben sind: • mHash Hashwert des Plaintext • padding Fixer Wert • salt Zufallswert 1. Ein Zufallswert salt wird generiert 2. Data Block 1 wird aus padding, mHash und salt zusammengestellt 3. Berechne Hash H aus Data Block 1 4. Forme Data Block 2 aus padding 2 und salt 5. Wende die Mask Generation Function MGF auf den Data Block 1 an 6. XOR‐verknüpfe die Maske mit dem Data Block 2 7. Stelle padded hash aus maskedDB, Hash und bc zusammen 8. Signiere padded hash mit dem Private Key salt mHash padding 1 Data Block 1 salt padding 2 Data Block 2 hash MGF bc maskedDB H padded hash Abbildung 12: Paddingvorgang bei PSS Wie auch OAEP, wird PSS von OpenSC 0.8.0 noch nicht unterstützt. Jan Keller Carla Schaffner 23 24.10.2003 Java Smartcard Unterstützung unter Linux 4.7. Grundlagen Digest Info Damit eine Signatur verifiziert werden kann, muss das Tool des Empfängers wissen, mit welchem Hashalgorithmus das Signaturprogramm den Message Digest erstellt hat. Aus diesem Grund müssen, bevor der Message Digest signiert wird (genauer gesagt bevor ein Paddingverfahren angewendet wird) Informationen an den Hash angehängt werden. Diese Informationen sind im DER‐Format in ein ASN.1‐Konstrukt verpackt. Dieses Konstrukt sieht folgendermassen aus: (asn1parse) 0: d=0 hl=2 l= 33 cons: SEQUENCE 2: d=1 hl=2 l= 9 cons: SEQUENCE 4: d=2 hl=2 l= 5 prim: OBJECT :z.B. sha1 11: d=2 hl=2 l= 0 prim: NULL 13: d=1 hl=2 l= 20 prim: OCTET STRING Die erste Zahl des asn1parse steht für den Offset des Objekts in Dezimal, d gibt die Tie‐ fe an, in der sich das Objekt befindet, hl ist die Headerlänge und l ist die Länge der Nutzdaten. plaintext ©J.åì±.š.L.só/é.I 0!0…+…...©J.åì±.š.L.só/é.I padding 20 Byte SHA1 35 Byte ASN.1 Konstrukt 93 Byte Padding 20 Byte H H H sha1 H ©J.åì±.š.L.só/é.I H 35 Byte Abbildung 13: Padding mit Digest Info Jan Keller Carla Schaffner 24 24.10.2003 Java Smartcard Unterstützung unter Linux Grundlagen In der Grafik ist sowohl die Signatur ersichtlich, als auch der Digest Info mit dem Wert SHA1. Jedes Objekt hat einen Header H der Länge 2. Das gelbe Objekt hat den Wert NULL und besteht somit nur aus einem Header. Wie ein Padding ohne OID aussieht, ist in Abbildung 10 gezeigt. Jan Keller Carla Schaffner 25 24.10.2003 Java Smartcard Unterstützung unter Linux 5. Problemanalyse Problemanalyse 5.1. Use Cases In diesem Kapitel werden mögliche Szenarien zur Verwendung von Smartcard unter‐ stützenden Anwendungen aufgezeigt. Eine mögliche Anwendung wäre, ein Smartcard unterstützter Login Prozess zu realisieren. Will ein Benutzer eine bestimmte Anwendung benützen, muss dieser sich authentifi‐ zieren. Dazu werden vom Server zuerst alle Zertifikate von der Karte gelesen und an‐ schliessend muss der Client einen ‐ vom Server erhaltenen ‐ Randomwert auf seiner Smartcard signieren. Die Signatur kann dann vom Server mittels Public Key verifiziert werden. Diese Anwendung kann in drei einzelne Anwendungsfälle aufgeteilt werden: 5.1.1. Zertifikate von der Smartcard lesen Damit der Server die erhaltene Signatur verifizieren kann, muss dieser über den Public Key des Benutzers verfügen. Das System benützt einen Provider um die Ver‐ bindung zur Smartcard zu eröffnen. Es werden alle Slots kontaktiert und das abge‐ legte Zertifikat ‐ falls vorhanden – wird abgerufen. 5.1.2. Signatur erstellen Vom System wird eine willkürliche Zeichenkette dem Benutzer geschickt. Dieser signiert die Zeichenkette auf der Smartcard. Das System kann nun mit dem Public Key des Benutzers diese Signatur verifizieren und so die Authentizität des Benut‐ zers sicherstellen. • Ist der Pin für den Private Key nicht korrekt, wird ein Fehler angezeigt und keine Signatur gemacht. • Ist in dem angegebenen Slot kein Private Key vorhanden, wird keine Signa‐ tur erstellt und einen Fehler angezeigt. Jan Keller Carla Schaffner 26 24.10.2003 Java Smartcard Unterstützung unter Linux 5.1.3. Problemanalyse Signatur verifizieren Die vom Client erstellte Signatur wird vom Server mittels des Public Keys verifi‐ ziert. Bei erfolgreicher Verifizierung wird ein positives Resultat dem Client ange‐ zeigt. • Bei Misserfolg wird dem Client eine Fehlermeldung angezeigt. 5.2. PKCS#11 / Cryptoki PKCS#11, oder auch Cryptographic Token Interface Standard genannt, spezifiziert eine Schnittstelle für Applikationen, die auf Token zugreifen, um kryptografische Operati‐ onen durchzuführen. Bei diesen Token kann es sich um Smartcards, USB‐Dongles oder PCMCIA‐Karten handeln. Die Implementierung dieser Schnittstelle unter Linux ist im nächsten Abschnitt kurz erläutert. 5.3. OpenSC Die OpenSC Workgroup realisierte mit ihrer libopensc‐Bibliothek ein PKCS#11‐API für den Zugriff auf Smartcards unter Linux. Sie stellt Basisfunktionen wie SELECT FILE, READ BINARY, usw. zur Verfügung, mit deren Hilfe auf jede ISO 7816‐4 kompatible Karte zugegriffen werden kann. Zudem sind RSA‐Kryptooperationen auf allen PKCS#15‐kompatiblen Karten möglich. Hauptsächlich werden die Plattformen Linux und Mac OS X unterstützt, gewisse Funktionen wurden auf Windows portiert. Neben den Bibliotheksdateien sind folgende Tools im OpenSC –Paket enthalten: • opensc‐tool für das Management der Reader, Treiber und Karten. • opensc‐explorer für den Zugriff auf die Files der Karte • pkcs15‐tool liest Objekte (Zertifikate, Schlüssel) von der Karte • pkcs15‐crypt ermöglicht RSA‐Entschlüsselung und digitale Signaturen mit PKCS#15‐Karten • pkcs15‐init für die Konfiguration der Karte. Jan Keller Carla Schaffner 27 24.10.2003 Java Smartcard Unterstützung unter Linux 5.4. Problemanalyse Java Native Interface (JNI) Da das PKCS#11 API lediglich C‐Funktionen zur Verfügung stellt, müssen diese mit Hilfe des Java Native Interface den Java Klassen bereitgestellt werden. Um dies zu rea‐ lisieren, muss in erster Linie ein Interface auf der Javaseite implementiert werden. Die‐ ses Interface wird mittels native Methoden gebildet. Aus diesem Interface wird dann ein Headerfile gebildet, in dem alle native Methoden deklariert werden und welches im C‐File, in dem die Funktionen implementiert sind, eingebunden wird. Im C‐Code müs‐ sen zudem Funktionsaufrufe, Parameterübergabe sowie Rückgabewerte angepasst werden. Dafür existieren im JNI spezielle Datentypen, welche durch so genannte Typ‐ cast’s6 eine Parameterübergabe von Java nach C und zurück ermöglichen. Zum Schluss muss das C‐File so kompiliert werden, dass ein .so‐File generiert wird, mit Hilfe dessen JNI die gewünschten Funktionen verwenden kann. Für die Ausfüh‐ rung muss das so.‐File (in der Microsoftwelt entspricht dies einer dll‐Datei) der Java Virtual Machine (JVM) zur Verfügung stehen. 5.5. Java Cryptography Architecture / Extension (JCA /JCE) Da es möglich sein soll, den in dieser Diplomarbeit zu realisierende Provider mit belie‐ bigen Java Anwendungen zu benützen, ist es notwendig, ein definiertes Interface zu verwenden. JCA und JCE schreiben vor, wie ein solcher Provider zu implementiert ist. Es ist möglich, dem System mehrere Provider anzugeben um so auch mehrere Services gebrauchen zu können. Mit dem J2SDK1.4.1 werden einige Provider von SUN mitge‐ liefert, die ohne spezielle Konfiguration verwendet werden können Datentypen von Java in Datentypen von C umwandeln und umgekehrt. 6 Jan Keller Carla Schaffner 28 24.10.2003 Java Smartcard Unterstützung unter Linux 6. Lösungskonzepte Lösungskonzepte 6.1. Übersicht X.509 Certificate Text Applikation readCertificate xt ( Str ) ing Certificate Object Te Signatur (byte[]) 1024 Bit RSA Signatur Class SHA1WithRSAEncryption MD5WithRSAEncryption Class Java SignatureWithRSA sh Ha ri n g (S t JNI ) Certificate (DER) Signatur (char) 128 Bit MD5 Hash 160 Bit SHA1 Hash Method Method signHash getCert(slot) ]) Ce rti fic a te ar[ []) char ch ( atur ( sh (D ER )* Sign Ha PKCS#11 C SD HW * 1 bis n wenn mehrere vorhanden Abbildung 14: Übersicht Jan Keller Carla Schaffner 29 24.10.2003 Java Smartcard Unterstützung unter Linux Applikation: Java C HW Lösungskonzepte Java Applikation, die den Provider benützt. Es werden die Services Signature und CertificateFactory angeboten. In der Java Ebene werden verschiedene API’s benützt. Zum einen JCE, welche gewährleistet, dass der Provider wie vorgeschrieben be‐ nützt werden kann. Andererseits wird JNI verwendet, um das Inter‐ face herzustellen, welches die Funktionen des in C geschriebenen PKCS#11 API für Java nutzbar macht. Die Programmteile in C sind die Schnittstelle zwischen Java und der Karte. Es werden sowohl die Funktionen des Cryptoki‐API für den Zugriff auf die Karte verwendet, als auch normale C‐Funktionen, welche die Informationen für Java aufbereiten. Beliebige ISO 7816‐4‐kompatible Smartcard, die über einen PC / SC‐ kompatiblen Reader angesprochen wird. 6.2. Lösungsvarianten Durch die fixe Aufgabenstellung und die Vorgabe der zu verwendenden API’s, erga‐ ben sich keine wirklich unterschiedlichen Lösungsvarianten. Abgesehen vom Fall, dass ein API den Anforderungen nicht vollständig gerecht wurde, wie im Kapitel 9.3 am Beispiel des Services CertificateFactory beschrieben. Deswegen wird hier nicht auf mögliche Varianten eingegangen. Jan Keller Carla Schaffner 30 24.10.2003 Java Smartcard Unterstützung unter Linux 6.3. Lösungskonzepte PC / SC Implementation Die Implementierung von PC/SC in der vorliegenden Arbeit sieht folgendermassen aus: Applikation KelschaJLin Service Provider PKCS#11 Cryptoki Service Provider pcscd ICC Resource Manager slbReflex72v2 IFD Handler RS-232 Reflex 72 IFD Cryptoflex Abbildung 15: Implementierung PC/SC Jan Keller Carla Schaffner 31 24.10.2003 Java Smartcard Unterstützung unter Linux 6.4. Lösungskonzepte Zustandsdiagramm der Smartcard Start End Abbildung 16: Smartcard‐Zustandsdiagramm Beim Verwenden der Smartcard müssen verschiedene Zustände durchlaufen werden, damit die Zertifikate gelesen oder die Signatur gemacht werden kann. 1. Zuerst wird der Reader kontaktiert. 2. War dies erfolgreich, kann eine Session auf einem bestimmten Slot geöffnet wer‐ den. 3. Wurde die Session eröffnet, kann das in diesem Slot gespeicherte Objekt gelesen werden, falls es nicht durch einen Pin gesichert ist. 4. Ist das Objekt durch einen Pin gesichert, ist zuerst ein Login nötig. 5. Nach korrektem Login können auch die geschützten Objekte verwendet werden. Es ist jedoch nie möglich, den Private Key von der Karte zu lesen. 6. Wurde ein Login durchgeführt, muss wieder ausgeloggt werden. 7. Danach kann die Session geschlossen werden. 8. Am Schluss wird die Verbindung wieder abgebaut. Jan Keller Carla Schaffner 32 24.10.2003 Java Smartcard Unterstützung unter Linux 6.5. Lösungskonzepte PKCS#11 API Die folgende Tabelle weist eine kurze Beschreibung der wichtigsten, verwendeten Cryptoki‐Funktionen auf, die im Headerfile pkcs11.h enthalten sind. Für dessen Verwendung muss das Shared Object File libopensc‐pkcs11.so beim kompilieren des Files SCConnection.c gelinkt werden. Weitere Informationen sind im RSA PKCS#11‐ Dokument zu finden. Alle Funktionen geben eine Konstante CK_RV zurück, die über den Erfolg der Funktion Auskunft gibt. Da diese Konstante eine nicht sehr aussagekräftige Zahl ist, wird sie mit der Methode CKK2Str() in einen benutzerfreundlichen String umgewandelt. Die möglichen Werte von CK_RV sind im Anhang B zu finden. CR_RV C_Initialize( Initialisiert die Cryptoki‐Bibliothek und baut pInitArgs Verbindung zu Reader auf. pInitArgs zeigt bei ) Multi‐Threaded‐Zugriff auf eine Parameterstruktur. C_Login( Loggt sich in ein Token ein. hSession hSession ist die gewünschte Sitzung. userType userType ist der Benutzertyp pPin pPin zeigt auf den Benutzer‐PIN ulPinLen ulPinLen Enthält die Länge des PINs ) C_FindObjectsInit( Bereitet die Suche nach Token oder Sitzungsobjekten hSession vor. pTemplate hSession ist die gewünschte Sitzung. ulCount pTemplate zeigt auf ein Suchmuster. ) ulCount enthält die Anzahl der Suchmuster. Um alle Objekte zu finden, ist ulCount auf 0 zu setzen. C_FindObjects( Führt die Suche nach Objekten aus. hSession hSession ist die gewünschte Sitzung. phObject phObject bekommt den Array von Objekten. ulMaxObjectCount ulMaxObjectCount: maximale Anzahl pulObjectCount Suchergebnisse ) pulObjectCount zeigt auf die Anzahl Suchergebnisse C_FindObjectsFinal( Beendet die Suche. hSession hSession ist die betreffende Sitzung. ) C_OpenSession( Eröffnet eine Sitzung zu einem spezifischen Slot. slotID slotID ist die ID des Slots flags flags definieren den Sessiontyp pApplication pApplication ist ein applikationspezifischer Zeiger Notify Notify ist die Adresse der callback function phSession ) phSession empfängt den session handler Jan Keller Carla Schaffner 33 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte C_GetSlotList( tokenPresent pSlotList pulCount ) Stellt Liste aller Slots im System zusammen. tokenPresent legt fest, ob alle Slots oder nur die leeren angezeigt werden sollen. pSlotList zeigt auf Buffer, der die Slotliste empfangen wird. pulCount enthält die Anzahl Slots. C_GetSlotInfo( slotID pInfo ) Sammelt Infos zu bestimmtem Slot. slotID ist die ID des Slots. pInfo zeigt auf den Speicherbereich, der die Infos empfängt. C_GetAttributeValue( hSession hObject pTemplate ulCount ) Liest die Attribute eines Objektes. hSession ist die gewünschte Sitzung. hObject ist das gewünschte Objekt. pTemplate ist ein Array, das die zu lesenden Attribute enthält und die Informationen empfängt. ulCount beinhaltet die Anzahl der Attribute. C_SignInit( hSession pMechanism hKey ) C_Sign( hSession pData ulDataLen pSignature pulSignatureLen ) Initialisiert eine Signaturoperation. hSession ist die aktuelle Sitzung. pMechanism zeigt auf den Signaturmechanismus. hKey ist der zu verwendende Schlüssel. C_Logout( hSession ) C_CloseSession( hSession ) C_Finalize( pReserved ) Loggt sich aus der gewünschten Sitzung aus. hSession ist die gewünschte Sitzung. Jan Keller Carla Schaffner Führt die Signatur aus. hSession ist die gewünschte Sitzung pData sind die zu signierenden Daten ulDataLen ist die Länge der Daten pSignature zeigt auf den Bereich, der die Signatur empfängt. pulSignatureLen ist die Länge der Signatur Schliesst die angegebene Sitzung. hSession ist die gewünschte Sitzung. Beendet die Verbindung von Applikation und Cryptoki‐Bibliothek. pReserved ist für zukünftige Anwendungen reserviert und sollte NULL sein. 34 24.10.2003 Java Smartcard Unterstützung unter Linux 6.6. Lösungskonzepte C_Sign / pMechanism Der Funktion C_Sign, oder genauer C_SignInit (siehe dazu Kapitel 6.5) muss der Parameter pMechanism mitgegeben werden, der ihr mitteilt, wie sie die Daten pData behandeln soll. Für die RSA‐Signatur stehen folgende Konstanten zur Auswahl: • CKM_RSA_PKCS • CKM_RSA_PKCS_OAEP • CKM_RSA_PKCS_PSS • CKM_RSA_X_509 • CKM_MD5_RSA_PKCS • CKM_SHA1_RSA_PKCS • CKM_SHA1_RSA_PKCS_PSS CKM_RSA_PKCS Wendet RSA PKCS#11 v1.5 Padding an und signiert pData. Sie kümmert sich nicht um die Form von pData. CKM_RSA_PKCS_OAEP Wendet RSA OAEP (siehe Kapitel 4.6.2) an und signiert pData. Wird CKM_RSA_PKCS_OAEP mit OpenSC verwendet, terminiert das Programm mit Fehler CKR_MECHANISM_INVALID. CKM_RSA_PKCS_PSS Wendet RSA PSS (siehe Kapitel 4.6.3) an und signiert pData. Wird CKM_RSA_PKCS_OAEP mit OpenSC verwendet, terminiert das Programm mit Fehler CKR_MECHANISM_INVALID. CKM_RSA_X509 Führt eine „raw“ RSA‐Signaturoperation gemäss X.509 durch, jedoch ohne Padding. CKM_MD5_RSA_PKCS Generiert von pData einen MD5‐Hash, padded gemäss PKCS#1 v1.5 und signiert die‐ sen anschliessend. CKM_SHA1_RSA_PKCS Generiert von pData einen SHA‐1‐Hash, padded gemäss PKCS#1 v1.5 und signiert diesen anschliessend. Jan Keller Carla Schaffner 35 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte CKM_SHA1_RSA_PKCS_PSS Generiert von pData einen SHA‐1‐Hash, padded gemäss RSA PSS (siehe Kapitel 4.6.3) und signiert diesen anschliessend. Um zwischen Java und C möglichst wenige Daten transferieren zu müssen, generiert der Provider KelschaJLin den Hash in Java. Das heisst Java bekommt einen Text als In‐ put, generiert den Hash und gibt ihn an C weiter. Deshalb verwendet die Funktion C_SignInit in diesem Fall den Mechanismus CKM_RSA_PKCS. 6.7. Digest Info in OpenSC Für die Signatur eines Hashwertes wird grob gesagt die Funktion C_Sign mit den Ar‐ gumenten pMechanism und pData aufgerufen. pMechanism zeigt auf einen in Kapi‐ tel 6.6 beschriebenen Mechanismus, der die Behandlung der Daten festlegt und pData zeigt auf die zu signierenden Daten. KelschaJLin verwendet wie bereits einmal erwähnt den neutralen Mechanismus CKM_RSA_PKCS. Wird nun C_Sign einen 160 Bit langen SHA‐1 Hash übergeben, kommt eine Signatur zurück, die nach der Verifikation, zusätzlich zum ursprünglichen Hash, noch eine Di‐ gest Info beinhaltet, obwohl C_Sign nie mitgeteilt wurde, um welchen Typ Hash es sich beim Input pData gehandelt hat. Auf dieses Phänomen angesprochen, bekamen wir von der OpenSC‐Developer‐ Mailingliste folgende Antwort: Hi, this is a ʹfeatureʹ of the opensc‐pkcs11 lib, that once appeared needed for Mozilla/Netscape. However, current versions of Mozilla/Netscape donʹt have this bug anymore, AFAIK, so I guess we should update to the correct way as well. (In fact, we allready agreed to change this, but it wasnʹt done yet out of fear for breaking something). For now, you could try to remove the lines with a ‐ in pkcs11/framework‐pkcs15.c and rebuild. break; case 36:flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; /* SSL hash */ break; ‐ case 20: ‐ flags |= SC_ALGORITHM_RSA_HASH_SHA1; /* SHA1 */ ‐ break; ‐ case 16: ‐ flags |= SC_ALGORITHM_RSA_HASH_MD5; /* MD5 */ Jan Keller Carla Schaffner 36 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte ‐ break; default: flags |= SC_ALGORITHM_RSA_HASH_NONE; If that works for your card, Iʹll try to make a decent patch shortly. Wie aus dem Source‐Code ersichtlich ist, legt C_Sign aufgrund der Länge des überge‐ benen Hashwertes fest um welchen Typ von Hash es sich handelt. SHA‐1 bei 20 Byte, MD5 bei 16 Byte. Sollten Probleme auftauchen (zum Beispiel, wenn ein MD2 Hash signiert werden soll, der bekanntlich die selbe Länge wie MD5 aufweist) oder sollte die Digest Info über‐ haupt nicht in die Signatur miteinbezogen werden, können die oben beschriebenen Zeilen auskommentiert werden. 6.8. Makros in C Mit der Methode C_GetAttributeValue stellt PKCS#11 eine Methode zur Verfü‐ gung, mit der diverse Informationen zu Objekten ermittelt werden können. Auch Kel‐ schaJLin benutzt diese Methode, um an Angaben wie KEY_TYPE, MODULUS_BITS, LABEL, ID und viele mehr heranzukommen. Um nicht für jede Information eine eigene Funktion schreiben zu müssen, wurden Makros definiert. Makros definieren, einfach gesagt, unter einem Namen einen Text. Der Precompiler ersetzt dann im Code den Namen durch den Text. Das heisst mit der Definition #define SCHREIBE (format, text) printf(„%“ #format „\n“, text) wird im Code jeder Aufruf SCHREIBE(s, „Hallo“); durch printf(„%s\n“,“Hallo“); ersetzt. Dieses Makro macht nicht sehr viel Sinn. Die Makros in KelschaJLin ersparen jedoch viel Schreibarbeit: Jan Keller Carla Schaffner 37 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte #define ATTR_METHOD(ATTR, TYPE) TYPE \ get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) \ { \ TYPE type; \ CK_ATTRIBUTE attr = { CKA_##ATTR, &type, sizeof(type) }; \ CK_RV rv; \ \ rv = C_GetAttributeValue(sess, obj, &attr, 1); \ if (rv != CKR_OK) \ printf("C_GetAttributeValue(" #ATTR ") %s\n", CKR2Str(rv)); \ return type; \ } Für jede gewünschte Funktion wird ein Makroaufruf geschrieben: ATTR_METHOD(CLASS, CK_OBJECT_CLASS); Beim Übersetzen ersetzt der Precompiler dann jeden Aufruf wie folgt durch die Mak‐ rodefinition: CK_OBJECT_CLASS getCLASS(CK_SESSION_HANDLE sess, \ CK_OBJECT_HANDLE obj) { CK_OBJECT_CLASS type; CK_ATTRIBUTE attr = {CKA_CLASS, &type, sizeof(type) }; CK_RV rv; rv = C_GetAttributeValue(sess, obj, &attr, 1); if (rv != CKR_OK) printf("C_GetAttributeValue(" CLASS ") %s\n", CKR2Str(rv)); return type; } Das heisst, dass es nach der Definition des Makros möglich ist, mit einer Zeile Code ei‐ ne 8‐zeilige Funktion zu erstellen. Die Funktion kann dann normal durch CK_OBJECT_CLASS getCLASS(CK_SESSION_HANDLE,CK_OBJECT_HANDLE); CK_OBJECT_CLASS cls = getCLASS(session, obj); aufgerufen werden. Jan Keller Carla Schaffner 38 24.10.2003 Java Smartcard Unterstützung unter Linux 6.9. Lösungskonzepte Implementierung des Java Native Interface 1. Wie schon erwähnt, sollen Funktionen die in C geschrieben wurden, in einer Java Klasse sichtbar gemacht werden. Dazu wird das JNI benutzt. In der Interface Klasse müssen diese C‐Funktionen, wie unten dargestellt public native static definiert werden. package ch.zhwin.da03.kelscha.provider; public class JNIForJLinProvider { public public public public public public public public public public public public native native native native native native native native native native native native static static static static static static static static static static static static String connect (); String login(String pin); String logout(); String listObjects(); String openSession(int slotNr); String getSlots(); String signHash(String hash); String disconnect(); String getCert(); int getNumberOfSlots(); boolean getFatal(); void setFatal(boolean fatal); static { System.loadLibrary("SCConnection"); } } Der Befehl System.loadLibrary(“SCConnection”); lädt die Bibliothek libSCConnection.so in die Java Klasse. Das libSCConnection.so enthält alle C‐Funktionen. 2. Aus dieser Java Klasse muss nun ein Headerfile generiert werden, das anschliessend im C‐File eingebunden wird. Zu diesem Zweck steht der Befehl javah zur Verfügung. Um den Befehl richtig auszuführen muss in das Verzeichnis, in dem das JNIForJLinProvider.class File liegt, gewechselt werden. (Falls die Klasse einem Package angehört, muss dies natürlich berücksichtigt und beim Aufruf angegeben werden). javah JNIForJLinProvider (ohne Package) javah ch.zhwin.da03.kelscha.provider. JNIForJLinProvider (mit Package) Dieses Headerfile muss nun ins Verzeichnis kopiert werden, in dem das zugehörige C‐ File liegt. Jan Keller Carla Schaffner 39 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte 3. Das eben generierte Headerfile sollte etwa so aussehen. Hier ist zu bemerken, dass bei dem richtigen Headerfile für jede im Interface definierte Methode ein Funktions‐ kopf erstellt wurde. Aus Übersichtsgründen wird hier nur ein Funktionskopf darge‐ stellt. /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class ch_zhwin_da03_kelscha_provider_JNIForJLinProvider */ #ifndef _Included_ch_zhwin_da03_kelscha_provider_JNIForJLinProvider #define _Included_ch_zhwin_da03_kelscha_provider_JNIForJLinProvider #ifdef __cplusplus extern "C" { #endif /* * Class: ch_zhwin_da03_kelscha_provider_JNIForJLinProvider * Method: connect * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provider_JNIForJLinProvider_connect (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif 4. Die C‐Funktionen müssen nun mit den erstellten Funktionsköpfen implementiert werden, damit JNI diese Funktionen findet. #include „ch_zhwin_da03_kelscha_provider_JNIForJLinProvider.h“ #include <opensc/pkcs11.h> #include <stdio.h> #include <stdlib.h> #include <stdbool.h> JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provider_JNIForJLinProvider_connect (JNIEnv * env, jclass cl){ sprintf(output,""); rv = C_Initialize(NULL); if (rv == CKR_OK) { sprintf(output, "Connection established\n"); } else { sprintf(output, "c_Initialize failed: %s\n",CKR2Str(rv)); Jan Keller Carla Schaffner 40 24.10.2003 Java Smartcard Unterstützung unter Linux } Lösungskonzepte fatal = TRUE; jstring retStr = NULL; retStr = (*env)->NewStringUTF(env, output); return retStr; } Um die Parameter und Rückgabewerte von C zu Java zu casten7, können vordefinierte Methoden benützt werden. Ein Beispiel ist:8 retStr = (*env)->NewStringUTF(env, output); 5. Das C‐File kann nun mit den folgenden Aufrufen kompiliert und gelinkt werden: gcc –c –fPIC –I /usr/lib/SunJava2-1.4.1/include/ –I /usr/lib/SunJava2-1.4.1/include/linux/ SCConnection.c Mit der Erstellung des Files SCConnection.o wird ein .so‐File generiert, das von der Java Klasse geladen wird. Sollen weitere .so‐Dateien mitgelinkt werden, muss dies wie folgt mit Flags angegeben werden: –L/<Link_Path> und –l<Link_Files>. Hier ist ein möglicher Aufruf dargestellt: gcc –shared –L/user/local/lib/pkcs11 –lpkcs11 –lopensc-pkcs11 –o libSCConnection.so SCConnection.o Das Java Native Interface sucht unter UNIX‐Systemen automatisch nach einer *.so‐ Datei mit dem Präfix lib. Deshalb muss dies beim Aufruf in der Klasse SCConnection (wie oben bereits gezeigt) nicht angeben werden. Um der Java Virtual Machine zu zeigen, wo sich die erzeugte, dynamisch ladbare Bib‐ liothek befindet, muss entweder die Umgebungsvariable LD_LIBRARY_PATH richtig gesetzt werden, oder aber die Datei an den richtigen Ort, nämlich nach /usr/lib/SunJava2-1.4.1/jre/lib/i386 kopiert werden. Alle Pfadangaben sind für Linux SUSE 8.2. Bei jeder anderen Distribution können die Pfadnamen abweichen. Datentypen umwandeln Weitere Angaben dazu sind im Buch „core JAVA 2“ zu finden. 7 8 Jan Keller Carla Schaffner 41 24.10.2003 Java Smartcard Unterstützung unter Linux 6.10. Lösungskonzepte Implementierung des Providers 1. Um einen Cryptographic Service Provider gemäss JCE zu implementieren, muss die Hauptklasse von der Klasse java.security.Provider abgeleitet werden. public final class KelschaJLinProvider extends Provider { Im Konstruktor kann nun durch den Aufruf super(provider_name, version, info); der Name, unter dem der Provider erreicht werden kann, gesetzt werden. Hier können auch Version und einige Informationen zu dem Provider angegeben werden. Danach müssen für alle Services eine Property‐Angabe mit Schlüssel und Wert ange‐ geben werden. put("Signature.SHA1WithRSAEncryption", "ch.zhwin.da03.kelscha.provider.SignatureWithRSA$SHA1WithRSAEncr yption"); Dies bedeutet, dass die beim Aufruf des SHA1WithRSAEncryption Algorithmus mit dem JLin Provider die Klasse ch.zhwin.da03.kelscha.provider.SignatureWithRAS$SHA1WithRSAEncry ption verwendet wird. Signature s = Signature.getInstance(„SHA1WithRSAEncription“, „JLin“); Zu jedem Service können auch Alias definiert werden. put("Alg.Alias.Signature.SHA1WithRSA", "SHA1WithRSAEncryption"); 2. Die einzelnen Serviceklassen ‐ beim KelschaJLin Provider die Klassen SignatureWithRSA und CertificateFactoryX509 ‐ müssen von speziellen Klassen (<Servicename>Spi) abgeleitet werden und deren abstrakte Methoden sind zu implemen‐ tieren. public class SignatureWithRSA extends SignatureSpi { public class CertificateFactoryX509 extends CertificateFactorySpi { Welche Methoden implementiert worden sind, wird im Kapitel 7.2.1.3 beschrieben. Jan Keller Carla Schaffner 42 24.10.2003 Java Smartcard Unterstützung unter Linux 6.11. Lösungskonzepte Kommunikation der Komponenten Nachfolgend ein Überblick über die Kommunikation zwischen den Komponenten am Beispiel einer Signatur. Um die Grafik nicht zu überladen, sind nur Befehle aufgeführt, die unmittelbar mit der Signatur zu tun haben. Vorangehende oder nachfolgende wurden weggelassen. Auf der linken Seite sind die Objekte aufgeführt und neben den Pfeilen die Funktio‐ nen, die aufgerufen werden beziehungsweise die ausgetauschten Informationen. Wie in Abbildung 17 ersichtlich ist, wird von der Applikation, die den KelschaJLin Pro‐ vider benützt und ein Signature Objekt instanziert hat, die Methode sign() aufge‐ rufen. Diese Methode wiederum ruft die Methode enginSign() auf. Durch die In‐ stanzierung des Objekts weiss das Objekt, welche Methode von welcher Klasse aufge‐ rufen werden muss. Durch diese Implementierung kann ein Provider „Plug and Play“ eingesetzt werden. Die Schnittstelle zur Anwendung bleibt gleich, nur ist es ein ande‐ rer Provider, der die Funktionen zur Verfügung stellt. Mehr zur Verwendung des Providers ist im Kapitel 10 zu finden. Jan Keller Carla Schaffner 43 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte Applikation y y y KelschaJLinProvider signature.sign() engineSign() y JNIForJLinProvider.signHash() y y C_SignInit() C_Sign() Provider (Java) Provider (C) opensc APDU’s als String pcscd APDU binäre APDU’s CLA INS P1 P2 P3 RSA Signature C0 88 00 01 80 Data Get Response C0 C0 00 00 00 Length Treiber APDU’s als elektrische Signale Karte Abbildung 17: Kommunikation der Komponenten Jan Keller Carla Schaffner 44 24.10.2003 Java Smartcard Unterstützung unter Linux 6.12. Lösungskonzepte Klassendiagramme Abbildung 18:Klasse KelschaJLinProvider Abbildung 19:Klasse CertificateFactoryX509 Abbildung 20: Klasse SignatureWithRSA Jan Keller Carla Schaffner 45 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte Abbildung 21: Klasse Util Abbildung 22:Klasse JNIForJLinProvider 6.13. Sequenzdiagramme Abbildung 23: Sequenzdiagramm Service CertificateFactory Jan Keller Carla Schaffner 46 24.10.2003 Java Smartcard Unterstützung unter Linux Lösungskonzepte Abbildung 24: Sequenzdiagramm Service Signature Jan Keller Carla Schaffner 47 24.10.2003 Java Smartcard Unterstützung unter Linux 7. Verwendete Komponenten Verwendete Komponenten 7.1. 7.1.1. Hardware Cryptoflex 8k In der vorliegenden Arbeit wurde die Cryptoflex 8k‐Smartcard von Schlumberger verwendet. Dabei handelt es sich um Mikroprozessorkarte mit folgenden Eigen‐ schaften: Kryptografische Funktionen: • RSA Signatur / Authentifizierung mit 512, 768 oder 1024 Bit • RSA Private Key Verschlüsselung / Entschlüsselung • 512, 768 oder 1024 Bit RSA Key Generation • SHA1 und MD5 Hashing • DES und Triple DES Verschlüsselung / Entschlüsselung (EBC & CBC) Hardware: • 7960 Bytes EEPROM • 153600 bits/s Übertragungsrate Unterstützte Plattformen: • PC/SC • PKCS#11 • Windows 2000 / XP 7.1.2. Reflex 72 V2 RS232 Reader Der Reflex 72‐Reader ist ein Peripheriegerät, das über die seriellen Schnittstelle mit dem Computer kommuniziert. Den Strom bezieht der Reader über die PS/2‐ Schnittstelle und ist dafür über einen Y‐Stecker, mit der Tastatur zusammen, am Keyboard‐Port eingesteckt. Weiter verfügt der Reader über einen Einschub für die Chipkarte. Technische Spezifikationen: • 8 gleitende Kontakte, ausgelegt für 100ʹ000 Einfügungen • Speisung: 5V vom PS/2 Port • Übertragungsrate zu PC: 56ʹ700 bps • Übertragungsrate zu Karte: 9600 bis 115ʹ200 bps • API: PC/SC Jan Keller Carla Schaffner 48 24.10.2003 Java Smartcard Unterstützung unter Linux 7.2. 7.2.1. Verwendete Komponenten Software Java Klassen Alle unten beschriebenen Klassen sind selber entwickelt. Häufig wurde ein beste‐ hendes Interface implementiert oder von einer bestehenden Java Klasse abgeleitet. 7.2.1.1. Klasse für die Providerschnittstelle KelschaJLinProvider.class Diese Klasse repräsentiert den eigentlichen Provider. Hier werden die möglichen Services angegeben. Der Provider bietet die Services Signature für MD5 und SHA1 Hashwerte und CertificateFactory, um alle X509 Zertifikate von der Smartcard zu lesen. Methoden Beschreibung public KelschaJLinProvider() Konstruktor für den Provider. Hier wer‐ den alle Services mittels Algorithmus‐ namen und zugehöriger Klasse angege‐ ben. 7.2.1.2. Klassen für den Service Signature SignatureWithRSA.class Diese Klasse ist für die Implementierung der Signatur zuständig. Sie ist von dem SignatureSpi abgeleitet und überschreibt die abstrakten Methoden der Super‐ klasse. Methoden Beschreibung public SignatureSKonstruktor der SignatureWithRSA‐ HA1WithRSA(String) Klasse, der den Service für die Signatur implementiert. Bei der Parameterüber‐ gabe wird der Algorithmus übergeben. protected void engineInitVeri- Mit dieser Methode kann der Public Key fy(PublicKey) für das Verifizieren der Signatur gesetzt werden. protected void engineInitMit dieser Methode könnte der Private Sign(PrivateKey) Key für das Signieren gesetzt werden. Soll das Signieren mit dem KelschaJLin Provider und einer Smartcard gemacht werden, kann bei der Parameterüberga‐ be nur null angegeben werden, da der Private Key in jedem Fall auf der Smart‐ card sein muss. Jan Keller Carla Schaffner 49 24.10.2003 Java Smartcard Unterstützung unter Linux protected void engineUpdate(byte) protected void engineUpdate(byte[]) protected void engineUpdate(byte, int, int) protected byte[] engineSign() protected boolean engineVerify(byte[]) protected void engineSetParameter (AlgorithmParameterSpec) private byte[] callCFunctions (String, int, int) Verwendete Komponenten Methode um die Daten, die signiert werden sollen, zu setzen bzw. updaten. Das übergebene byte wird angefügt. Hier kann der Klartext9 mit einem byte[] ergänzt werden. Mit dieser Methode können die Daten ergänzt werden. Das byte[] wird bei dem angegeben Offset eingefügt. Der dritte Parameter bezeichnet die Länge des byte[]. Beim Aufruf dieser Methode wird der eigentliche Signiervorgang getätigt. Der Rückgabewert beinhaltet die Signatur in Form eines byte[]’s. Hier kann eine Signatur verifiziert wer‐ den. Diese Methode wird gebraucht, um der Signature Engine einige Parameter zu setzen, falls notwendig (z.B. Slot, Pin) Private Methode, die die Kommunikati‐ on mit der Smartcard übernimmt. Die gewünschten C‐Funktionen werden mit‐ tels dem JNI Interface aufgerufen. Diese Methode gibt einen byte[] mit der Signa‐ tur zurück. Konnte aus irgendeinem Grund keine Signatur erstellt werden, wird ein leerer byte[] zurückgegeben. Da für die Signatur ein Algorithmus gesetzt werden muss, wird für jeden der ver‐ schiedenen Algorithmen eine eigene Klasse geschrieben. Diese Klassen werden alle von der Superklasse SignatureWithRSA abgeleitet, damit alle gemeinsamen Metho‐ den übernommen werden können. So muss beim Konstruktor nur der Name des Algorithmus gesetzt werden. Die nachfolgenden zwei Klassen sind solche Algo‐ rithmenklassen und enthalten nur einen Konstruktor, der die Methode super(algName) mit dem jeweiligen Algorithmus aufruft. SHA1WithRSAEncryption.class Methoden Beschreibung public SHA1WithRASEncryption() Konstruktor der Klasse SHA1WithRSAEncryption. Unverschlüsselte Daten. Wird auch als Plaintext bezeichnet. 9 Jan Keller Carla Schaffner 50 24.10.2003 Java Smartcard Unterstützung unter Linux MD5WithRSAEncryption.class Methoden public MD5WithRASEncryption() Verwendete Komponenten Beschreibung Konstruktor der Klasse MD5WithRSAEncryption. SignatureParameterSpec.class Um der Signatur einige Parameter zu setzen, wurde diese Klasse implementiert. Sie implementiert das Interface AlgorithmParameterSpec. Methoden Beschreibung public SignatureParameFür die Instanzierung eines SignatuterSpec(int, int) reParameterSpec Objekt müssen zwei int‐Werte übergeben werden. Diese sind für die Übergabe des Slots und des Pins des Private Keys nötig. public int getPin() Gibt den Pin für den Private Key zurück. public int getSlot() Diese Methode gibt den Slot, in dem der Private Key liegt, zurück. 7.2.1.3. Klassen für den Service CertificateFactory CertificateFactoryX509.class Diese Klasse implementiert den Service eines CertificateFactory. Sie wird von der Klasse CertificateFactorySpi abgeleitet und implementiert alle abstrakten Methoden dieser Superklasse. Methoden Beschreibung public CertificateFactoKonstruktor für die Klasse CertificaryX509() teFactoryX509. public Certificate engineGene- Diese Methode wird bei dem KelschaJLin rateCertificate Provider nicht unterstützt. Erklärung (InputStream) siehe Kapitel 9.3. public Collection engineGeneMethode um alle Zertifikate von der rateCertificates Smartcard zu lesen und ein Certifi(InputStream) cate Objekt zu generieren. Benützt die Hilfsklasse CertificateReader. public CRL engineGenerateCerAuch diese Methode wird nicht imple‐ tificate mentiert und wirft bei Aufruf eine Exep‐ (InputStream) tion. public Collection engineGeneEbenso wird diese Methode bei dem JLin rateCRLs Provider nicht unterstützt. (InputStream) Jan Keller Carla Schaffner 51 24.10.2003 Java Smartcard Unterstützung unter Linux Verwendete Komponenten CertificateReader.class Diese Klasse ist eine eigene Klasse und nicht von einem JCE Service Provider Inter‐ face abgeleitet. Die Klasse CertificateReader übernimmt die eigentliche Gene‐ rierung der Zertifikate, nachdem sie von der Smartcard gelesen wurden. Methoden Beschreibung public CertificateReader() Konstruktor für die Klasse CertificateReader. Wird kein Argument über‐ geben, so werden alle Slots der Smart‐ card nach Zertifikaten abgesucht. public CertificateReader(int) Wird bei der Instanzierung der Klasse CertificateReader ein int überge‐ ben, so wird nur das Zertifikat aus dem angegebenen Slot gelesen (falls eines vorhanden). public Vector getCerts() Diese Methode gibt einen Vector mit allen Zertifikaten zurück. Falls sich kein Zertifikat in diesem Slot befindet, wird eine Exception geworfen. private Certificate maMethode um von dem erhaltenen Hex‐ keX509Cert(String) Stream, der in einem ByteArrayInutStream gespeichert wurde, ein Certificate Objekt zu generieren. Dazu wird ein Service eines anderen, von JDK mitgelieferten, Providers be‐ nutzt. private boolean readCertFromS- Beim Aufruf dieser Methode wird eine martcard(int) Connection zu der Smartcard geöffnet und bei dem angegebenen Slot das Zerti‐ fikat gelesen und in einen ByteArrayInutStream geschrieben. Jan Keller Carla Schaffner 52 24.10.2003 Java Smartcard Unterstützung unter Linux 7.2.1.4. Verwendete Komponenten Klasse für Utilities die beide Services benützen Util.class Diese Klasse stellt einige Methoden zur Verfügung, die von mehreren Klassen benö‐ tigt werden. Methoden Beschreibung public static String stringTo- Konvertiert einen ASCII‐String in einen Hex(String) String mit dessen Hex‐Wert. public static byte[] hexKonvertiert einen Hex‐String in einen StringToByteArray ASCII‐String und gibt diesen in einem (String) byte[] zurück. public static void checkTestet einen String ob es sich um einen String(String) Fehler‐Output von C‐Code handelt. Wenn ja wird dieser auf die Komman‐ dozeile ausgegeben. 7.2.2. C Die C‐Komponenten stellen die Verbindung zwischen dem Java‐Provider und dem hardwarenahen Cryptoki‐API her. Alle Methoden geben einen char‐String zurück, der von Java verarbeitet wird. SCConnection.c Methoden Beschreibung JNIEXPORT jstring JNICALL Initialisiert eine Verbindung zur ICC. Java_ch_zhwin_da03_kelscha_pro Sollte dies fehlschlagen, ist der Reader vider_JNIForJLinProvider_conne nicht ansprechbar. ct(JNIEnv * env, jclass cl) Eröffnet eine Sitzung zum Token in Slot JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi Nummer slotNr. der_JNIForJLinProvider_openSes sion (JNIEnv * env, jclass cl, jint slotNr) Authentifiziert sich bei der Karte der JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi aktuellen Sitzung. Dadurch werden die PIN‐geschützten Objekte sichtbar. der_JNIForJLinProvider_login (JNIEnv * env, jclass cl, jstring pin_input) JNIEXPORT jstring JNICALL JaGibt alle Objekte (Keys, Zertifikate) der va_ch_zhwin_da03_kelscha_provi aktuellen Sitzung zurück. Ohne vorheri‐ der_JNIForJLinProvider_listObj ges Login wird der Private Key nicht ects (JNIEnv * env, jclass cl) zurückgegeben. Jan Keller Carla Schaffner 53 24.10.2003 Java Smartcard Unterstützung unter Linux JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_getSlot s (JNIEnv * env, jclass cl) JNIEXPORT jint JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_getNumb erOfSlots (JNIEnv * env, jclass cl) JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_getCert (JNIEnv * env, jclass cl) JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_signHas h (JNIEnv * env, jclass cl, jstring hash_input) JNIEXPORT jboolean JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_getFata l (JNIEnv * env, jclass cl) JNIEXPORT void JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_setFata l (JNIEnv * env, jclass cl, jboolean fat) JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_logout (JNIEnv * env, jclass cl) JNIEXPORT jstring JNICALL Java_ch_zhwin_da03_kelscha_provi der_JNIForJLinProvider_disconn ect (JNIEnv * env, jclass cl) Verwendete Komponenten Listet Informationen zu allen Slots der aktuellen Sitzung auf. Gibt die Anzahl Slots der aktuellen Sit‐ zung zurück. Gibt alle Zertifikate der aktuellen Sit‐ zung im DER Format zurück. Signiert den Digest hash[] (hex) mit dem Private Key der aktuellen Sitzung und gibt die Signatur als Hexwert zurück. Gibt die Variable „fatal“ zurück. Bei ei‐ nem schwerwiegenden Fehler ist diese TRUE und das Programm sollte angehal‐ ten werden. Setzt „fatal“ je nach Aufruf auf TRUE oder FALSE. Logout der aktuellen Session. Beendet die Verbindung zur Smartcard. Jan Keller Carla Schaffner 54 24.10.2003 Java Smartcard Unterstützung unter Linux 8. Tests Tests Alle Tests wurden auf einer Workstation mit Betriebssystem Linux SUSE 8.2. ausgeführt und gemäss der Anleitung in Anhang F installiert. Unterschrift der Testperson: …………………….. Datum: …………………….. 8.1. SignatureWithRSA.class engineIntiVerifiy(PulbicKey) Äquivalenzklassen: Beim Aufruf der Methode wird: 1a) ein RSAPublicKey Objekt übergeben. 1b) ein PublicKey der kein RSAPublicKey Objekt ist, übergeben. 1c) null übergeben. Testfall 1 2 3 getestete Äquiva‐ 1a) 1b) 1c) lenzklasse Vorbedingung ‐ Signature Ob‐ ‐ Signature Ob‐ ‐ Signature Ob‐ jekt mit dem JLin jekt mit dem JLin jekt mit dem JLin Provider muss er‐ Provider muss er‐ Provider muss er‐ zeugt sein. zeugt sein. zeugt sein. Test Aufruf von initAufruf von initAufruf von initVeriVeriVerify(null) fy(PublicKey) fy(PublicKey) Erwartetes Resultat PublicKey Objekt InvalidKeyExNull kann nicht wird gesetzt ception, da der übergeben werden, Parameter kein da die Methode RSAPublicKey Ob‐ überladen ist und jekt ist. es so nicht eindeu‐ tig ist, um welche Methode es sich handelt. Reaktion b b b Jan Keller Carla Schaffner 55 24.10.2003 Java Smartcard Unterstützung unter Linux Tests engineInitSign(PrivateKey) Äquivalenzklassen: Beim Aufruf der Methode wird: 2a) ein PrivateKey Objekt übergeben. 2b) null übergeben. Testfall 4 5 getestete Äquivalenzklasse 2a) 2b) Vorbedingung ‐ Signature Objekt mit ‐ Signature Objekt mit dem JLin Provider muss dem JLin Provider muss erzeugt sein. erzeugt sein. Test Aufruf von initAufruf von initSign(PrivateKey) Sign(null) Erwartetes Resultat InvalidKeyException, Keine Exception. Initiali‐ da der Private Key auf der sierung wurde erfolgreich erledigt. Smartcard sein muss. Reaktion b b engineUpdate(byte)/ (byte[])/ (byte[],int,int) Äquivalenzklassen: Beim Aufruf der Methode wird: 3a) ein byte / byte[] / byte[], int, int übergeben. 3b) null übergeben. Testfall 6 7 getestete Äquivalenzklasse 3a) 3b) Vorbedingung ‐ Signature Objekt mit ‐ Signature Objekt mit dem JLin Provider muss dem JLin Provider muss erzeugt sein. erzeugt sein. Aufruf von upTest 1. Aufruf von update(null) date(byte) 2. Aufruf von update(byte[]) 3. Aufruf von update(byte[], int, int) Erwartetes Resultat Daten, die signiert werden Darf nicht übergeben wer‐ sollen, werden mit jeweili‐ den. NullPointerExgem Input upgedatet. ception. Reaktion 1. b b 2. b 3. b Jan Keller Carla Schaffner 56 24.10.2003 Java Smartcard Unterstützung unter Linux Tests engineSetParameter(AlgorithmParameterSpec) Äquivalenzklassen: Beim Aufruf der Methode wird: 4a) ein SignatureParameterSpec Objekt übergeben. 4b) irgendein anderes AlgorithmParameterSpec Objekt übergeben. Testfall 8 9 getestete Äquivalenzklasse 4a) 4b) Vorbedingung ‐ Signature Objekt mit ‐ Signature Objekt mit dem JLin Provider muss dem JLin Provider muss erzeugt sein. erzeugt sein. Aufruf von setParameTest Aufruf von setParameter (AlgorithmParater (AlgorithmParameterSpec) meterSpec) Erwartetes Resultat Aus dem übergebenen InvalidAlgorithmPaObjekt werden Slotnum‐ rameterException, da mer und Pin gelesen. Objekt ein SignatureParameterSpec Objekt sein muss. Reaktion b b engineSign() Äquivalenzklassen: 5a) korrekter Slot und Pin (0, 1111) 5b) unkorrekter Slot (13, 1111) 5c) korrekter Slot unkorrekter Pin (0, 1112) 5d) korrekter Slot, jedoch kein Zertifikat enthalten (3, 0000) 5e) virtueller Slot (7, 0000) 5f) keine Smartcard im Reader Testfall 10 11 getestete Äquivalenzklasse 4a) 5a) 4a) 5b) ‐ Signature Objekt mit Vorbedingung ‐ Signature Objekt mit dem JLin Provider muss dem JLin Provider muss erzeugt sein. erzeugt sein. ‐ initSign(null) muss ‐ initSign(null) muss aufgerufen sein. aufgerufen sein. ‐ setParameter (Algo- ‐ setParameter (AlgorithmParameterSpec) rithmParameterSpec) Test Aufruf von sign() Aufruf von sign() Erwartetes Resultat Signatur wird gemacht InvalidParameterException, da kein Slot ge‐ funden wurde. Reaktion b b Jan Keller Carla Schaffner 57 24.10.2003 Java Smartcard Unterstützung unter Linux Tests Testfall 12 getestete Äquivalenzklasse 4a) 5c) Vorbedingung ‐ Signature Objekt mit dem JLin Provider muss erzeugt sein. ‐ initSign(null) muss aufgerufen sein. ‐ setParameter (AlgorithmParameterSpec) Test Aufruf von sign() Erwartetes Resultat Keine Signatur wird er‐ stellt. Fehler werden aus‐ gegeben. Reaktion b 13 4a) 5d) ‐ Signature Objekt mit dem JLin Provider muss erzeugt sein. ‐ initSign(null) muss aufgerufen sein. ‐ setParameter (AlgorithmParameterSpec) Aufruf von sign() Keine Signatur wird er‐ stellt. Fehler werden auge‐ geben. b Testfall 14 getestete Äquivalenzklasse 4a) 5e) Vorbedingung ‐ Signature Objekt mit dem JLin Provider muss erzeugt sein. ‐ initSign(null) muss aufgerufen sein. ‐ setParameter (AlgorithmParameterSpec) Test Aufruf von sign() Erwartetes Resultat Keine Signatur wird er‐ stellt. Fehler werden aus‐ gegeben. Reaktion b 15 4a) 5f) ‐ Signature Objekt mit dem JLin Provider muss erzeugt sein. ‐ initSign(null) muss aufgerufen sein. ‐ setParameter (AlgorithmParameterSpec) Aufruf von sign() Keine Signatur wird er‐ stellt. Fehler werden aus‐ gegeben. b engineVerify(byte[]) Äquivalenzklassen: 6a) Aufruf der Methode Testfall 16 getestete Äquivalenzklasse 1a) 6a) Vorbedingung ‐ Signature Objekt mit dem JLin Provider muss er‐ zeugt sein. ‐ initVerify(PublicKey) muss aufgerufen sein. Test Aufruf von verify(byte[]) Erwartetes Resultat Methode wirft beim Aufruf sofort UnsupportedOperationException, da diese Methode nicht unterstützt ist. Reaktion b Jan Keller Carla Schaffner 58 24.10.2003 Java Smartcard Unterstützung unter Linux 8.2. Tests CertificateFactoryX509.class engineGenerateCertificate(InputStream) Äquivalenzklassen: 7a) Jeglicher Aufruf der Methode Testfall 17 getestete Äquivalenzklasse 7a) Vorbedingung ‐ CertificateFactory Objekt mit dem JLin Provider muss erzeugt sein. Test Aufruf der Methode engineGenerateCertificate(InputStream) Erwartetes Resultat UnsupportedOperationException, da kein Slot gesetzt werden kann, können immer nur alle Zertifikate gelesen werden. Reaktion b engineGenerateCertificates(InputStream) Äquivalenzklassen: Beim Aufruf der Methode wird der Parameter: 8a) null übergeben. 8b) ein InputStream übergeben. Testfall 18 19 getestete Äquivalenzklasse 8a) 8b) Vorbedingung ‐ CertificateFactory ‐ CertificateFactory Objekt mit dem JLin Pro‐ Objekt mit dem JLin Pro‐ vider muss erzeugt sein. vider muss erzeugt sein. Test Aufruf der Methode enAufruf der Methode engineGenerateCertifi- gineGenerateCertificates(null) cates(InputStream) Erwartetes Resultat Es werden alle Zertifikate CertificateExceptivon der Smartcard ausge‐ on, da die Zertifikate im‐ lesen und in einer Colmer von der Smartcard lection zurückgegeben. gelesen werden. Reaktion b b Jan Keller Carla Schaffner 59 24.10.2003 Java Smartcard Unterstützung unter Linux Tests engineGenerateCRL(InputStream) Äquivalenzklassen: 9a) Jeglicher Aufruf der Methode Testfall 20 getestete Äquivalenzklasse 9a) Vorbedingung ‐ CertificateFactory Objekt mit dem JLin Provider muss erzeugt sein. Test Aufruf der Methode engineGenerateCRL(InputStream) Erwartetes Resultat UnsupportetOperationException. Reaktion b engineGenerateCRLs(InputStream) Äquivalenzklassen: 10a) Jeglicher Aufruf der Methode Testfall 21 getestete Äquivalenzklasse 10a) Vorbedingung ‐ CertificateFactory Objekt mit dem JLin Provider muss erzeugt sein. Test Aufruf der Methode engineGenerateCRLs(InputStream) Erwartetes Resultat UnsupportetOperationException. Reaktion b Jan Keller Carla Schaffner 60 24.10.2003 Java Smartcard Unterstützung unter Linux 8.3. Tests CertificateReader.class readCertFromSmartcard(int) Äquivalenzklassen: Beim Aufruf der Methode wird: 11a) eine Slotnummer, die ein Zertifikat enthält übergeben. (1) 11b) eine Slotnummer, die kein Zertifikat enthält übergeben. (3) 11c) eine ungültige Slotnummer übergeben (5) Testfall 22 23 24 getestete Äquiva‐ 11a) 11b) 11c) lenzklasse ‐ Certifi‐ CertifiVorbedingung ‐ CertificateReader() cateReader() cateReader() oder Certificaoder Certificaoder CertificateReader(int) teReader(int) teReader(int) muss instanziert muss instanziert muss instanziert sein. sein. sein. Test Bei der Instanzie‐ rung wird die Me‐ thode readCertFromSmartcard(int) aufge‐ rufen. Erwartetes Resultat Die Karte wird kontaktiert, eine Session auf den angegebenen Slot eröffnet, das Zerti‐ fikat gelesen und in eine ByteArrayInputStream ab‐ gelegt. Reaktion b Bei der Instanzie‐ rung wird die Me‐ thode readCertFromSmartcard(int) aufge‐ rufen. Karte kann kontak‐ tiert werden, Sessi‐ on wird geöffnet. Da dieser Slot kein Zertifikat enthält wird eine SlotNotContainCertException ge‐ worfen. b Bei der Instanzie‐ rung wird die Me‐ thode readCertFromSmartcard(int) aufge‐ rufen. Die Smartcard kann kontaktiert werden, jedoch ist es nicht möglich eine Session zu eröffnen, da die Karte nur 4 Slots unterstützt. Eine SlotNotContainCertException wird gewor‐ fen. b Jan Keller Carla Schaffner 61 24.10.2003 Java Smartcard Unterstützung unter Linux makeX509Cert() Äquivalenzklassen: Beim Aufruf der Methode wird: 12a) ByteArrayInputStream ist null. 12b) ByteArrayInputStream ist nicht null. Testfall 25 getestete Äquivalenzklasse 12a) Vorbedingung ‐ CertificateReader() oder CertificateReader(int) muss instanziert sein. ‐ Methode readCertFromSmartcard(int) wurde aufge‐ rufen. Test makeX509Cert() wird aufgerufen. Erwartetes Resultat Certificate Objekt wird von dem vorher gele‐ senen ByteArrayInputStream erzeugt. Reaktion b getCerts() Äquivalenzklassen: 13a) Mehrere Zertifikate wurden erzeugt. 13b) Ein Zertifikat wurde erzeugt. Testfall 27 getestete Äquivalenzklasse 13b) Vorbedingung ‐ CertificateReader() muss instanziert sein. ‐ Für jeden Slot müssen die Methoden readCertFromSmartcard(int) und makeX509Cert() aufgeru‐ fen worden sein. Test Erwartetes Resultat Reaktion Jan Keller Carla Schaffner getCerts() wird aufge‐ rufen. Alle erstellten Zertifikate werden in einem Vector zurückgegeben. b 62 Tests 26 12b) ‐ CertificateReader() oder CertificateReader(int) muss instanziert sein. ‐ Methode readCertFromSmartcard(int) wurde aufge‐ rufen. makeX509Cert() wird aufgerufen. CertificateException wird geworfen, da InputStream null ist. b 28 13a) ‐ CertificateReader() oder CertificateReader(int) muss instanziert sein. ‐ Methode readCertFromSmartcard(int) wurde aufge‐ rufen. ‐makeX509Cert() wurde aufgerufen getCerts() wird aufge‐ rufen. Ein Zertifikat wird in dem Vector zurückgegeben. b 24.10.2003 Java Smartcard Unterstützung unter Linux 8.4. Tests Util.class hexStringToByteArray(String) Äquivalenzklassen: Beim Aufruf der Methode wird: 14a) ein String bestehend aus Hexzahlen übergeben. 14b) beliebiger String übergeben. Testfall 29 getestete Äquivalenzklasse 14a) Vorbedingung ‐ Klasse Util ist final und die Methode static, deshalb kann sie ohne Vorbedingung aufgerufen werden. Test Aufruf der Methode. Erwartetes Resultat „Hexstring“ wird geparst und in ein byte[] gefüllt. Reaktion b 30 14b) ‐ Klasse Util ist final und die Methode static, deshalb kann sie ohne Vorbedingung aufgerufen werden. Aufruf der Methode. String kann nicht umge‐ setzt werden, da es sich nicht um Hexzeichen han‐ delt. NumberFormatException. b stringToHex(String) Äquivalenzklassen: Beim Aufruf der Methode wird: 15a) ein beliebiger String, bestehend aus Buchstaben übergeben. 15b) ein beliebiger String, bestehend aus Zahlen übergeben. Testfall 31 32 getestete Äquivalenzklasse 15a) 15b) Vorbedingung Klasse Util ist final und Klasse Util ist final und die Methode static, des‐ die Methode static, des‐ halb kann sie ohne Vorbe‐ halb kann sie ohne Vorbe‐ dingung aufgerufen wer‐ dingung aufgerufen wer‐ den. den. Test Aufruf der Methode. Aufruf der Methode. Erwartetes Resultat Der String wird in Hexzah‐ Der String wird in Hexzah‐ len gewandelt. len gewandelt. Reaktion b b Jan Keller Carla Schaffner 63 24.10.2003 Java Smartcard Unterstützung unter Linux 8.5. Tests JNIForJLinProvider.class connect() Äquivalenzklassen: 16a) PC/SC Dämon ist gestartet. (pcscd) 16b) Dämon ist nicht gestartet. Testfall 33 34 getestete Äquivalenzklasse 16a) 16b) Vorbedingung Test connect() wird aufgeru‐ connect() wird aufgeru‐ fen. fen. Erwartetes Resultat Connection zu Smartcard Connection kann nicht Reader wird eröffnet. eröffnet werden. Reaktion b b Bei allen weitern Tests wird davon ausgegangen, das der PC/SC Dämon gestartet ist. openSession(int) Äquivalenzklassen: Beim Aufruf der Methhode: 17a) ist keine Karte im Reader. 17b) ist eine Karte im Reader und erlaubter Slot wird gewählt. (1) 17c) ist eine Karte im Reader und unerlaubter Slot wird gewählt. (6) Testfall 35 36 37 getestete Äquiva‐ 16a), 17a) 16a), 17b) 16a), 17c) lenzklasse Vorbedingung ‐ Methode con‐ Methode con‐ Methode connect() wurde nect() wurde nect() wurde aufgerufen. aufgerufen. aufgerufen. Test openSession(1) openSession openSession wird aufgerufen. (1) wird aufgeru‐ (6) wird aufgeru‐ fen. fen. Erwartetes Resultat Keine Session kann Session auf Slot mit Session kann nicht eröffnet werden. der Nummer 1 eröffnet werden. wird eröffnet. Reaktion b b b Jan Keller Carla Schaffner 64 24.10.2003 Java Smartcard Unterstützung unter Linux Tests getNumberOfSlots() Äquivalenzklassen: 18a) Zuvor wurde die Mehtode connect() aufgerufen. 18b) Die Methode connect() wurde nicht aufgerufen. Testfall 38 39 getestete Äquivalenzklasse 16a), 18a) 18b) Vorbedingung Test getNumberOfSlots() getNumberOfSlots() wird aufgerufen. wird aufgerufen. Erwartetes Resultat 8 0 Reaktion b b getFatal() Äquivalenzklassen: 19a) Aufruf der Methode, ohne jemals eine andere Methode, die den boolean fa‐ tal hätte setzten können aufgerufen wurde. Testfall 40 getestete Äquivalenzklasse 19a) Vorbedingung Test getFatal() wird aufgerufen. Erwartetes Resultat false Reaktion b setFatal(boolean) Äquivalenzklassen: Beim Aufruf der Methode wird: 20a) der Parameter true übergeben. 20b) der Parameter false übergeben. Testfall 41 42 getestete Äquivalenzklasse 19a), 20a) 19a), 20b) Vorbedingung Aufrufen von: Test setFatal(true) wird aufgerufen. Anschliessend setFatal(tue) die Methode getFatal() getFatal() setFatal(false) um den neu gesetzten getFatal() Wert zu kontrollieren. Erwartetes Resultat true true false Reaktion b b Jan Keller Carla Schaffner 65 24.10.2003 Java Smartcard Unterstützung unter Linux Tests getSlots() Äquivalenzklassen: 21a) Zuvor wurde die Mehtode connect() aufgerufen. 21b) Die Methode connect() wurde nicht aufgerufen. Testfall 43 44 45 getestete Äquiva‐ 16a), 21a) 16a), 21a) 21b) lenzklasse Vorbedingung ‐ Karte im Reader. ‐ Keine Karte im ‐ Karte im Reader. Reader. Test getSlots() wird getSlots() wird getSlots() wird aufgerufen. aufgerufen. aufgerufen. Es werden nur die Es kann nicht auf Erwartetes Resultat Alle vorhandenen die Slots zugegrif‐ Slots die der Rea‐ Slots werden mit den Informationen der untersützt aus‐ fen werden. Fehler wird ausgegeben. gegeben. Informa‐ Hersteller, Hard‐ tioen zu Hersteller, ware, Firmware Hardware und und Token ausge‐ Firmware. geben. Reaktion b b b listObjects() Äquivalenzklassen: 22a) Session auf erlaubten Slot eröffnet (1). 22b) Session auf unerlaubten Slot eröffnet (7). Testfall 46 47 getestete Äquivalenzklasse 16a), 17b), 22a) 16a), 17b), 22b) Vorbedingung ‐ connect() und ‐ connect() und ‐ openSession(1) wur‐ ‐ openSession(1) wur‐ den aufgerufen. den aufgerufen. Test Aufruf der Methode Aufruf der Methode listObjects(). listObjects(). Erwartetes Resultat Es werden alle Objekte die Es können keine Objekte sich im Slot 1 befinden gelesen werden. ausgelesen. Reaktion b b Jan Keller Carla Schaffner 66 24.10.2003 Java Smartcard Unterstützung unter Linux login(String) Äquivalenzklassen: 23a) Login mit richtigem Pin (Bei Slot 1 Pin 2222). 23b) Login mit falschem Pin (Bei Slot 1 Pin 1234). Testfall 48 getestete Äquivalenzklasse 16a), 17b), 23a) Vorbedingung ‐ connect() und ‐ openSession(1) wur‐ den aufgerufen. Test Aufruf der Methode login(“2222“). Erwartetes Resultat Login erfolgreich. Reaktion b getCert() Äquivalenzklassen: 24a) Von Slot mit Zertifikat (0). 24b) Von Slot ohne Zertifikat (3). Testfall 50 getestete Äquivalenzklasse 16a), 17b), 24a) Vorbedingung ‐ connect() und ‐ openSession(0) wur‐ den aufgerufen. Test Aufruf der Methode getCert(). Erwartetes Resultat Liest Zertifikat in Slot 0. Reaktion b Tests 49 16a), 17b), 23b) ‐ connect() und ‐ openSession(1) wur‐ den aufgerufen. Aufruf der Methode login(“1234“). Login ist fehlgeschlagen. b 51 16a), 17b), 24b) ‐ connect() und ‐ openSession(3) wur‐ den aufgerufen. Aufruf der Methode getCert(). Es kann kein Zertifikat gelesen werden, da Slot 3 kein Zertifikat enthält. b signHash(String) Äquivalenzklassen: Beim Aufruf der Methode: 25a) wird ein String übergeben. Testfall 52 getestete Äquivalenzklasse 16a), 17b), 23a), 25a) Vorbedingung ‐ connect() , ‐ openSession(1) und ‐ login(“2222“) wurden aufgerufen. Test Aufruf der Methode signHash(“2765397a6e“). Erwartetes Resultat Hashwert wird signiert. Reaktion b Jan Keller Carla Schaffner 67 24.10.2003 Java Smartcard Unterstützung unter Linux logout() Äquivalenzklassen: 26a) Aufruf der Methode. Testfall 53 getestete Äquivalenzklasse 16a), 17b), 23a), 26a) Vorbedingung ‐ connect() , ‐ openSession(1) und ‐ login(“2222“) wurden aufgerufen. Test Aufruf der Methode logout(). Erwartetes Resultat Ausloggen ohne Fehler. Reaktion b closeSession() Äquivalenzklassen: 27a) Aufruf der Methode. Testfall 55 getestete Äquivalenzklasse 16a), 17b), 27a) Vorbedingung ‐ connect() und ‐ openSession(1) wurden aufgerufen. Test Aufruf der Methode closeSession(). Erwartetes Resultat Session kann ohne Fehler geschlossen werden. Reaktion b Tests 54 16a), 17b), 26b) ‐ connect() und ‐ openSession(1) wurden aufgerufen. Aufruf der Methode logout(). Fehler beim ausloggen, da vorgängig kein Login ge‐ macht wurde. b 56 16a), 27a) ‐ connect() wurden aufgerufen. Aufruf der Methode closeSession(). Fehler beim Schliessen der Session, da keine Session eröffnet wurde. b disconnect() Äquivalenzklassen: 28a) Aufruf der Methode. Testfall 57 58 getestete Äquivalenzklasse 16a), 28a) 28a) Vorbedingung - connect() wurden aufgerufen. Test Aufruf der Methode dis- Aufruf der Methode disconnect(). connect(). Erwartetes Resultat Smartcard Reader wird Fehler da Smartcard Rea‐ disconnect. der nicht connected war. Reaktion b b Die Outputs von diesen Tests sind auf der mitgelieferten CD zu finden. Jan Keller Carla Schaffner 68 24.10.2003 Java Smartcard Unterstützung unter Linux 9. Probleme Probleme 9.1. ASCII to Hex Zwischen C und Java (und umgekehrt) werden Strings wie Hashwerte oder Signaturen übergeben, die unter anderem nicht darstellbare Zeichen enthalten. Um sicherzustel‐ len, dass keine Zeichen falsch interpretiert oder erst gar nicht übergeben werden, sind diese Strings als ASCII‐Hexwerte kodiert. Das heisst ihr Hexwert wird als String über‐ tragen. Der Text „test“ (Hexwert 74:65:73:74) wird zum Beispiel als „74657374“ übergeben. 9.1.1. C Beim Empfang des zu signierenden Hash (Quellarray hash[]) von Java ist nun zu beachten, dass in diesem Char‐Array jeder Hexwert doppelt so viel Platz braucht als eigentlich nötig. Der Text „test“ besteht aus vier mal einem Byte gleich 4 Byte. Binär sieht dies fol‐ gendermassen aus: 0111’0100 0110’0101 0111’0011 0111’0100 74h 65h 73h 74 t e s t Nun wird der Text in Java in den Hex‐ASCII‐String „74657374“ umgewandelt und belegt somit 8 Byte: 0011’0111 0011’0100 0011’0110 0011’0101 0011’0111 0011’0011 0011’0111 0011’0100 37h 34h 36h 35h 37h 33h 37h 34h 7 4 6 5 7 3 7 4 Wird nun in C der erhaltene ASCII‐Hexwert mit einer FOR‐Schleife Byte‐für‐Byte zurückgewandelt, for (i=0;i<hashLen;i++) { hexData[i]=char2hex(hash[i]); } Jan Keller Carla Schaffner 69 24.10.2003 Java Smartcard Unterstützung unter Linux char char2hex (char alphanum) Probleme { switch (alphanum) { case '0': return '\x0';break; case '1': return '\x1';break; case '2': return '\x2';break; case '3': return '\x3';break; case '4': return '\x4';break; case '5': return '\x5';break; case '6': return '\x6';break; case '7': return '\x7';break; case '8': return '\x8';break; case '9': return '\x9';break; case 'a': return '\xa';break; case 'b': return '\xb';break; case 'c': return '\xc';break; case 'd': return '\xd';break; case 'e': return '\xe';break; case 'f': return '\xf';break; default: exit(0); } } kommt ein völlig falscher Wert raus: 0000’0111 0000’0100 0000’0110 0 000’0101 0000’0111 0000’0011 0000’0111 0000’0100 07h 04h 06h 05h 07h 03h 07h 04h BEL EOT ACK ENQ BEL ETX BEL EOT Das Problem wird folgendermassen gelöst: Ein Char‐Array wird definiert, in dem an den Adressen der ASCII‐Zeichen 0 bis 9, a bis f und A bis F deren Wert im Hexadezimalsystem gespeichert ist. Konkret wird an der Adresse 61 (Hexwert des Zeichens ‚a’) der Wert 10 gespeichert, weil das Zeichen a im Hexadezimalsystem den Wert 10 hat. 30 31 32 33 0 1 2 3 ... 63 64 65 66 12 13 14 15 67 ... Abbildung 25: Hilfsarray unsigned char hex[] = ['0'] = 0, ['4'] = 4, ['8'] = 8, ['c'] = 12, ['A'] = 10, ['E'] = 14, Jan Keller Carla Schaffner { ['1'] ['5'] ['9'] ['d'] ['B'] ['F'] = = = = = = 1, ['2'] 5, ['6'] 9, ['a'] 13, ['e'] 11, ['C'] 15}; 70 = = = = = 2, 6, 10, 14, 12, ['3'] ['7'] ['b'] ['f'] ['D'] = = = = = 3, 7, 11, 15, 13, 24.10.2003 Java Smartcard Unterstützung unter Linux Probleme Nun wird der HexData‐Array (Zielarray) durchwandert. Für jedes Zeichen wird auf den oben beschriebenen Zwischenarray zugegriffen und der Wert an der Adresse des betreffenden Zeichens zurückgegeben. Für das erste Zeichen des Quellarray (7) würde das bedeuten, es wird auf die Ad‐ resse 37 (Hexwert von 7) zugegriffen, und der Wert an dieser Stelle (7) zurückgege‐ ben. Erst Sinn macht dieser Zwischenarray, wenn das Zeichen des Quellarray ein Buchstabe – zum Beispiel a – ist und dann der Wert 10 an der Adresse 61 zurückge‐ geben wird. Danach wird das zweite Zeichen aus dem Quellarray gelesen und nachgeschlagen. Das zuvor gelesene Zeichen wird um 4 Bit nach links geschoben und mit dem zwei‐ ten zusammen in den ersten Char von hexData geschrieben. Nun stehen die ersten beiden Zeichen des Quellarray (ursprünglich 16 Bit) im ers‐ ten Byte des Zielarray. for (i=0;i<hexDataLen;i++) { hexData[i] = (hex[hash[2*i]] << 4)+hex[hash[2*i+1]]; } 9.1.2. Java Nach dem eigentlichen Signiervorgang, wird die Signatur in einem Hex‐String an Java übergeben. Dieser Hex‐String wird anschliessend in einen byte[] zurück kon‐ vertiert. Dazu wurde eine static‐Methode implementiert, welche die final‐ Klasse Util zur Verfügung stellt. Methodenkopf: Es muss ein Hex‐String bestehend aus Hex‐Zeichen übergeben werden. Wird ein String mit anderen Zeichen übergeben, wird eine Exception ge‐ worfen. public static byte[] hexStringToByteArray (String hex) { Ein byte[] mit halber Länge des Strings wird erzeugt, da immer 2 Zeichen in ein byte geschrieben werden. byte[] cert_bytes = new byte[hex.length()/2]; Mit einer for‐Schleife wird durch den ganzen Array gelaufen. for (int j = 0; j < cert_bytes.length; j++) { Immer zwei Zeichen werden von dem String gelesen. String help = hex.substring(j*2, j*2+2); Jan Keller Carla Schaffner 71 24.10.2003 Java Smartcard Unterstützung unter Linux Probleme Mit dieser Methode kann ein String zu der Basis 16, also hexadezimal, geparst wer‐ den. int decimal_value = Integer.parseInt(help, 16); Dieser int kann danach in ein byte gecastet werden und dem Array angefügt wer‐ den. byte dec_byte = (byte)decimal_value; cert_bytes[j] = dec_byte; } return cert_bytes; } Beispiel: Wird der String „54657374“ der Methode hexStringToByteArray über‐ geben byte[] b = hexStringToByteArray(“54657374”); gibt es folgenden Returnwert: Test Mit dieser Methode können also alle von der Smartcard erhaltenen Hex‐Strings konvertiert werden. Dies wird bei dem KelschaJLin Provider sowohl bei der Signatur als auch beim Lesen der Zertifikate verwendet. 9.2. Entschlüsseln mit C_Decrypt Neben dem Signieren von Texten mit dem auf der Smartcard gespeicherten Schlüssel wäre es auch interessant, Dokumente, die einem verschlüsselt zugeschickt wurden, mit dem Private Key zu entschlüsseln. Der PKCS#11‐Standard sieht dafür die Funktion C_Decrypt vor. Zu Beginn dieser Arbeit war die Decrypt‐Funktion in OpenSC leider noch nicht imp‐ lementiert, wodurch es nicht möglich war, den Provider mit einer Entschlüsselungs‐ funktion auszustatten. Eine dafür geschriebene Testapplikation terminierte mit dem Fehler CKR_FUNCTION_NOT_SUPPORTED. Wie wir in der letzten Woche unserer Diplomarbeit erfahren haben, wurde die Funkti‐ on C_Decrypt am 1.10.2003 in die OpenSC Bibliothek aufgenommen. Die Zeit reichte jedoch nicht mehr, um das neue Release zu installieren und den CSP mit dieser Funk‐ tion auszustatten. Auszug auf dem File http://www.opensc.org/files/ChangeLog‐opensc: Jan Keller Carla Schaffner 72 24.10.2003 Java Smartcard Unterstützung unter Linux 2003-10-01 09:51 Probleme Stef Hoeben <[email protected]> *src/: pkcs11/framework-pkcs15.c (1.93), pkcs11/mechanism.c (1.11), pkcs11/pkcs11-object.c (1.27), pkcs11/sc-pkcs11.h (1.60), tools/pkcs11-tool.c (1.48): Added C_DecryptInit() and C_Decrypt() for RSA keys 9.3. JCE Bei der Implementierung des Providers sind einige Probleme mit den Service Provider Interfaces (Spi) von JCE aufgetreten. Beim genaueren Betrachten der Schnittstellen wurde festgestellt, dass diese nicht für die Verwendung von Cryptotoken vorgesehen sind. Deshalb musste einiges mit eigenen Klassen und Methoden realisiert werden. Nun wird auf diese eigenen Lösungen genauer eingegangen. 9.3.1. Service CertificateFactory Bei der herkömmlichen CertificateFactory können Zertifikate mit den Metho‐ den generateCertificate(InputStream) und generateCertificates(InputStream) generiert werden. Falls keine Smartcards benutzt werden, macht dies durchaus Sinn. Sollen aber die Zertifikate der Smartcards für die kryp‐ tographischen Anwendungen verwendet werden, ist dies nicht ausreichend. Smart‐ cards sind in verschiedene Slots aufgeteilt. In diesen Slots können Zertifikate, Public Keys oder Private Keys abgelegt werden. Soll nun genau ein Zertifikat von der Smartcard gelesen werden, ist diese mit der oben erwähnten generateCertificate‐Methode nicht direkt abrufbar, da die gewünschte Slotnummer angegeben werden muss. Aus diesem Grund wurden folgende Überlegungen zur Realisierung gemacht: 9.3.1.1. Slotnummer in InputStream verpacken Eine Möglichkeit wäre, die Slotnummer in den InputStream zu verpacken. Diese Variante wäre auf jeden Fall realisierbar, ist jedoch unschön. Eine Parameterüberga‐ be sollte, wenn möglich, nicht für andere Zwecke als vorgesehen verwendet wer‐ den. Jan Keller Carla Schaffner 73 24.10.2003 Java Smartcard Unterstützung unter Linux 9.3.1.2. Probleme Immer alle Zertifikate lesen Um die Schnittstelle von JCE nicht zu verändern, bestünde die Möglichkeit, immer alle Zertifikate zu lesen. Auf diese Weise ist es jedoch nicht möglich eine Slotnum‐ mer zu wählen. Ist nur ein Zertifikat auf der Karte, ist dies egal. Liegen jedoch meh‐ rere Zertifikate auf der Smartcard, werden beim Aufruf immer alle Zertifikate zu‐ rückgegeben. Somit ist es eine Sache der Anwendung, das gewünschte Zertifikat zur Verfügung zu stellen. 9.3.1.3. Eigene CertificateFactory Klasse mit Methoden erweitern Eine weitere Möglichkeit wäre, die selber geschriebene Service Klasse der CertificateFactory mit eigenen Methoden zu erweitern. So können die Parameter, wie zum Beispiel die Slotnummer übergeben werden. Doch diese Lösung kann so nicht realisiert werden, da die Methoden der eigenen Klassen nicht direkt aufgeru‐ fen werden. Wird das Beispiel der CertificateFactory genommen, werden ja eigentlich die Methoden des CertificateFactory Objekt aufgerufen. CertificateFactory cf = CertificateFactory.getInstance("X509", "JLin"); Collection col = cf.generateCertificates(null); In der Methode der Klasse CertificateFactory wird dann die Methode engineGenerateCertificates(InputStream) aufgerufen. Werden also in der ei‐ genen Provider Klasse weitere Methoden geschrieben, können diese dennoch nicht aufgerufen werden, da die Klasse java.security.cert.CertificateFactory diese Methoden für den Benutzer nicht anbietet. 9.3.2. Entscheid und Lösung Um die erwähnten Probleme zu lösen, wurde entschieden, dass nur der Provider Service angeboten wird, der alle Zertifikate von der Smartcard liest. Deshalb kann nur die Methode generateCertificates(null) aufgerufen werden. Bei allen anderen Methoden dieses Services wird eine Exception geworfen. Es ist zu beach‐ ten, dass beim Aufruf der Parameter null übergeben werden muss. Collection col = cf.generateCertificates(null); Der Grund dafür ist, dass der Provider keinen InputStream akzeptiert, sondern sich diesen direkt von der Smartcard holt. Um dennoch den Service anzubieten zu können, ein Zertifikat aus einem ausge‐ wählten Slot zu lesen, wurde die Klasse CertificateReader erstellt. Diese Klasse Jan Keller Carla Schaffner 74 24.10.2003 Java Smartcard Unterstützung unter Linux Probleme ist das Mittelstück der CertificateFactory und dient ‐ unter Verwendung wei‐ terer Klassen ‐ der Kommunikation mit der Smartcard. Wird diese Klasse mit einer Parameterübergabe instanziert, so kann das Zertifikat eines einzelnen Slots gelesen werden. CertificateReader crWithSlotNr = new CertificateReader(1); In diesem Fall wird das Zertifikat, das sich im Slot 1 befindet, gelesen. Zu erwähnen ist jedoch, dass dieser Service nicht mehr dem JCE‐Gedanken ent‐ spricht. Es wird jedoch der Vollständigkeit halber mit dem Provider geliefert. 9.4. Signieren des Providers In der Dokumentation von JCE wird geraten, dass jeder Provider der auf JCE beruht sein eigenes jar‐File signieren sollte. Da Sun für die Signatur eine Firma voraussetzt, war es leider nicht möglich für den KelschaJLin Provider ein von SUN unterschriebenes Zertifikat plus eine Unterschrift zu erhalten. Wieso sollte ein Provider überhaupt mit einem Zertifikat unterschrieben werden? Bei modularen Anwendungen, bei denen Zusätze mehr oder weniger „Plug and Play“ eingefügt werden können, besteht ein erhöhtes Sicherheitsrisiko. Es wäre möglich, den korrekten Provider mit einem anderen, eventuell bösartigen Provider, auszutauschen ohne dass es gemerkt würde. Da dieser Provider nicht zum Vertrieb gedacht ist, wurde diese Signatur des Jar‐Files nicht gemacht. Wird jedoch ein CSP von einer Firma entwickelt, zur Verfügung gestellt und vertrieben, ist die Signatur des Provider‐jar’s zu empfehlen. Jan Keller Carla Schaffner 75 24.10.2003 Java Smartcard Unterstützung unter Linux 9.5. Probleme Digest Info Wird mit dem Provider KelschaJLin ein Text signiert und danach mit dem OpenSSL‐ Tool verifiziert, meldet OpenSSL eine ungültige Signatur, obwohl sowohl Text als auch Schlüssel übereinstimmen. Dies hängt mit dem Padding dieser beiden Tools zusammen. Während OpenSSL direkt auf den 160‐Bit‐Sha1‐Hash das PKCS#1 v1.5 Paddingverfahren anwendet, schreibt Kel‐ schaJLin noch ein ASN.1 Konstrukt mit der Digest Info vor den Hashwert (siehe Kapitel 6.7) und macht erst dann das Padding. (siehe Kapitel 4.7) Wenn nun OpenSSL die Signatur überprüft und dabei Widererwarten ein Hash mit vorangestelltem Digest Info herauskommt, meldet es eine ungültige Signatur. Erläuterndes Beispiel: Wir erstellen mit einem Tool, das Digest Infos anhängt (zum Beispiel pkcs11‐tool) eine Signatur SA und generieren mit einem Tool, das Digest Infos nicht unterstützt (OpenSSL) einen Hash B vom gleichen Text. Nach Verifikation von SA mit OpenSSL erhalten wir einen 35 Byte grossen „Hash“ A, der in den ersten 15 Bytes jedoch noch das ASN.1 Konstrukt enthält. Der Vergleich von A und B schlägt logischerweise fehl. Nach Entfernen des ASN.1‐Konstrukts (das heisst nach Abschneiden der ersten 15 Bytes) ist ein erfolgreicher Vergleich möglich. 9.6. Verwenden der mitgelieferten OpenSC Files Das OpenSC‐Projekt liefert die nötigen Header‐ und .so‐Files für das PKCS#11 API mit. Dies bedeutet, dass nach der Installation der OpenSC‐Tools ‐wie in Anhang F be‐ schrieben ‐ diese Files zur Verfügung stehen. Damit die C‐Funktionen des API’s ge‐ funden werden, müssen jedoch noch einige Manipulationen getätigt werden. Nach vie‐ len Tests konnte festgestellt werden, dass ein .so‐File umbenannt und beim kompilie‐ ren mitgelinkt werden muss. Dieses File liegt im Verzeichnis /usr/local/lib/pkcs11 und heisst opensc‐pkcs11.so . Es muss nach libopensc‐pkcs11.so umbenannt werden. Bei der Installation des Providers wird dies mit dem Ausführen des Makefile, wie in Anhang F beschrieben, erledigt. Jan Keller Carla Schaffner 76 24.10.2003 Java Smartcard Unterstützung unter Linux 10. Verwendung des Providers Verwendung des Providers Der implementierte Provider soll von jeder Java Applikation verwendet werden können. Aus diesem Grund wurde der Provider mit dem JCE implementiert. Damit ist gewährleis‐ tet das der Provider „Plug and Play“ eingesetzt werden kann. Die Einbindung und Ver‐ wendung des KelschaJLin Providers unterscheidet sich nicht von den SUN‐eigenen Provi‐ der. Um einen eigenen Provider benützen zu können muss er zuerst eingebunden werden. Dies kann auf zwei verschiedene Arten geschehen. 10.1. Dynamisches Einbinden Wird der Provider dynamisch in die Applikation geladen, kann dieser nur dort und nur während der Laufzeit benützt werden. Dazu wird zum Beispiel in dem Konstruktor der Klasse, die den Provider benützen will, der Aufruf Security.addProvider(new KelschaJLinProvider()); gemacht. Somit kann der Provider benützt werden und ist unter seinem Namen anzu‐ sprechen. Natürlich muss die Klasse ch.zhwin.da03.kelscha.provider.KelschaJLinProvider importiert werden und im Classpath das zugehörige JLin.jar‐File angegeben werden. 10.2. Statisches Einbinden Soll der Provider statisch eingebunden werden, kann das java.security Properties File editiert werden. Dieses File ist im Verzeichnis <java_home>/lib/security/java.security zu finden. Mit <java_home> ist der Pfad, an dem das J2SDK1.4.1 installiert ist, gemeint. Bei SUSE 8.2 liegt das File unter: /usr/lib/SunJava2-1.4.1/jre/lib/security Jan Keller Carla Schaffner 77 24.10.2003 Java Smartcard Unterstützung unter Linux Verwendung des Providers Dieses File kann nun mit einem Editor folgendermassen ergänzt werden. # # List of providers and their preference orders (see above): # security.provider.1=sun.security.provider.Sun security.provider.2=com.sun.net.ssl.internal.ssl.Provider security.provider.3=com.sun.rsajca.Provider security.provider.4=com.sun.crypto.provider.SunJCE security.provider.5=sun.security.jgss.SunProvider # Eigener Provider security.provider.6= ch.zhwin.da03.kelscha.provider.KelschaJlinProvier Das zugehörige .jar‐File, in diesem Fall das File JLin.jar, muss in das jre Verzeichnis von Java kopiert werden, damit die nötigen Klassen für den Provider gefunden wer‐ den. Pfad bei SUSE 8.2: /usr/lib/SunJava2-1.4.1/jre/lib/ext Der Provider mit der Nummer Eins ist der Standard Provider. Wird ein Service aufge‐ rufen, werden die Provider den Nummern (1 bis 6) nach durchsucht bis ein Provider gefunden wird, der den Service anbietet. Soll der Service eines bestimmten Providers aufgerufen werden, muss dies beim Aufruf angegeben werden. Signature sig = Signature.getInstance("MD5WithRSA", "JLin"); Wird der Service Signature bereits von einem vorgängigen Provider unterstützt, wird dennoch der Service des KelschaJLin Provider benützt. 10.3. Service Signature des Providers benützen Nach dem Einbinden können nun die vom Provider zur Verfügung gestellten Services benützt werden. Dank den Interfaces und Superklassen, die implementiert wurden kann durch den Aufruf Signature sig = Signature.getInstance("SHA1WithRSA", "JLin"); der Signature Service des KelschaJLin Provider instanziert werden. Danach können alle Methoden der Instanz Signature aufgerufen werden. Bevor die Methode sign() aufgerufen werden kann, muss die Methode initSign(Private Key) und setParameter(SignatureParameterSpec) aufgerufen werden. Der Parameter Jan Keller Carla Schaffner 78 24.10.2003 Java Smartcard Unterstützung unter Linux Verwendung des Providers bei initSign(null), der übergeben wird, muss null sein, da kein Private Key ge‐ setzt werden kann. Dies wurde so gelöst, weil sich damit der Benutzer des Providers im Klaren sein sollte, dass der Private Key immer auf der Karte liegt und dort auch die Signatur erstellt wird. Die Methode setParameter (SignatureParameterSpec) muss zwingend aufgerufen werden, weil darin sowohl Slot des gewünschten Private Keys, als auch zugehöriger Pin gesetzt werden. Untenstehend wird der korrekte Auf‐ ruf der Methoden dargestellt. sig.initSign(null); sig.setParameter(new SignatureParameterSpec(slot, pin)); Da nun eine Signatur eines Textes gemacht werden soll, ist es natürlich auch notwen‐ dig, den Text zu setzten. Dies kann mit den Methoden update(…) gemacht werden. sig.update(input); Beim Aufruf dieser Methoden wird laufend auch der Hashwert aktualisiert, der schlussendlich an die Smartcard geschickt und dort signiert wird. Dadurch ist die Per‐ formance besser, da nur 160 oder 128 Bit, je nach Algorithmus, an die Karte geschickt werden müssen und nicht alle Daten. Zu guter letzt wird nun die Methode sign() aufgerufen, welche die eigentliche Signa‐ tur erstellt. Diese Methode gibt einen byte[], der die Signatur enthält zurück. sig.sign(); 10.4. Service CertificateFactory des Providers benützen Damit die eben signierten Daten auch verifiziert werden können, ist es unumgänglich, diejenigen Zertifikate, die auf der Smartcard liegen, abzurufen. Dazu gibt es den Servi‐ ce CertificateFactory. Da die gespeicherten Zertifikate im X.509 Format sind, ist der Algorithmus, der bei der Instanzierung übergeben werden muss, X509. CertificateFactory cf = CertificateFactory.getInstance("X509", "JLin"); Nach dem Erzeugen einer CertificateFactory Instanz des Providers JLin können nun dessen Methoden aufgerufen werden. Jan Keller Carla Schaffner 79 24.10.2003 Java Smartcard Unterstützung unter Linux Verwendung des Providers Dazu ist zu erwähnen, dass bei diesem Provider nicht alle Methoden unterstützt wer‐ den, da dies in der vorgegebenen Zeit nicht alles hätte implementiert werden können und deshalb nicht Teil der Aufgabenstellung war. Es wird nur die Methode generateCertificates(InputStream) unterstützt. Soll diese Methode korrekt ausge‐ führt werden, das heisst alle auf der Smartcard abgelegten Zertifikate werden abgeru‐ fen und als Certificate Objekt in einer Collection zurückgegeben, muss der Pa‐ rameter null übergeben werden. Dies wurde so gelöst, damit sich der Benutzer be‐ wusst sein ist, dass die Zertifikate auf der Smartcard liegen und nicht in einem InputStream übergeben werden können. Wird dennoch ein InputStream übergeben, wird eine Exception geworfen. Collection col = cf.generateCertificates(null); Die Collection enthält nun alle auf der Smartcard abgelegten Zertifikate in Form von X509Certificate Objekten. Diese Objekte können für die Verifizierung ver‐ wendet werden. Wie schon erwähnt ist es nicht möglich mit diesem Provider nur ein einziges Zertifikat von der Karte abzurufen. Es sei denn, es ist nur ein einziges Zertifikat auf der Smart‐ card vorhanden. Um ein einzelnes Zertifikat zu lesen, müsste der CertificateFactory eine Slotnummer übergeben werden können, was leider mit der gegebenen Su‐ perklasse CertificateFactorySpi nicht möglich ist. Diese Spi Klasse unterstützt leider keine Methode bei der irgendwelche Parameter gesetzt werden könnten. 10.5. Verifizieren der erstellten Signatur Damit das Signieren einen Sinn macht, soll die erstellte Signatur natürlich auch verifi‐ ziert werden. Der Provider KelschaJLin untersützt diese Funktion nicht. Dazu kann je‐ doch ein in J2SDK1.4.1 mitgelieferter Provider benützt werden. Damit verifiziert werden kann, muss jedoch auch das zum Private Key gehörende Zer‐ tifikat und somit der Public Key von der Smartcard geladen werden. Dies kann mit dem Service CertificateFactory des KelschaJLin Providers erledigt werden. Wie dieser Service zu verwenden ist, ist in Kapitel 10.4 erläutert. Es muss also ein Signature Objekt mit einem mitgelieferten Provider erstellt werden. Dabei muss darauf geachtet werden, dass bei der Instanzierung derselbe Algorithmus angegeben wird wie bei dem Signieren. Signature sig = Signature.getInstance(("MD5WithRSA"); Jan Keller Carla Schaffner 80 24.10.2003 Java Smartcard Unterstützung unter Linux Verwendung des Providers Nun muss der Public Key für die Verifizierung gesetzt werden. Dazu ist die Methode s.initVerify(cert.getPublicKey()); aufzurufen. cert ist das mit der CertificateFactory generierte Certificate Objekt. Mit der Methode getPublicKey() wird der Public Key dieses Zertifikates zu‐ rückgegeben und kann somit gesetzt werden. Da ein neues Signature Objekt erzeugt wurde, muss auch der zu verifizierende Text mit update(…) angegeben werden. sig.update(input); Nun kann mit der Methode boolean correct = sig.verify(signature); die Signatur verifiziert werden. Zu beachten ist, dass dieser Methode die Signatur (in einem byte[]) genau so übergeben werden muss, wie sie von sign() zurückgeben wurde. Als Rückgabewert wird ein boolean zurückgegeben. True falls die beiden Hashwerten übereinstimmen, false, wenn nicht. Jan Keller Carla Schaffner 81 24.10.2003 Java Smartcard Unterstützung unter Linux 11. Offene Punkte / Schlusswort Offene Punkte Wie bereits in Kapitel 9.2 erwähnt, sollte es nun möglich sein, die Funktion C_Decrypt mit dem neusten OpenSC‐Release verwenden zu können. Somit könnte der KelschaJLin Provi‐ der in einer späteren Version um eine Entschlüsselungsfunktion erweitert werden, die es ermöglicht, verschlüsselte Daten mit dem Private Key auf der Smartcard zu entschlüsseln. 12. Schlusswort Wie wir sehr bald feststellten, war die grösste Herausforderung dieser Arbeit das Pro‐ grammieren in der Sprache C, und zwar weil keiner von uns Erfahrungen mit dieser Pro‐ grammiersprache hatte. Es dauerte eine gewisse Zeit, bis wir die PKCS#11‐Funktionen korrekt aufrufen konnten, die richtigen Headerfiles importierten und alle .so‐Dateien link‐ ten. Auch die spärlichen Fehlermeldungen des Compilers und die Verwendung von Zei‐ ger bereiteten uns Anfangs einige Probleme. Natürlich nahmen wir diese Herausforderung gerne an und haben dadurch neben dem angeeigneten diplomarbeitsbezogenen Wissen über Smartcards und Linux, sogar noch eine neue Programmiersprache kennen gelernt. Auch unser Wissen betreffend Java durf‐ ten wir um Erfahrungen im Umgang mit CSP’s, JCE / JCA und JNI erweitern. Für die hilfsbereite Unterstützung bei unseren Problemen und die gute Zusammenarbeit möchten wir Herrn Steffen ganz herzlich danken. Bei diversen Ausschweifungen in alle Ecken der IT‐Security‐Welt erfuhren wir auch abseits des Pfades der Diplomarbeit sehr interessante Dinge. Weiter gilt unser Dank auch unseren Familien, Freunden und allen, die auf irgendeine Art zum erfolgreichen Abschluss dieser Diplomarbeit beigetragen ha‐ ben. Wie gewohnt nicht ohne zwischenzeitige Hochs und Tiefs, ist das Endprodukt nun auf einem zufrieden stellenden Stand, der bei Bedarf problemlos erweitert werden kann. Nicht ohne Stolz werden wir uns in Zukunft gerne an diese intensiven Wochen und vor allem an das damit verbundene Ziel zurückerinnern. Jan Keller Carla Schaffner 82 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Anhang A. Glossar APDU Eine APDU (application protocol data unit) ist ein softwaretechnischer Datencontainer, in den die Daten einer Anwendung verpackt werden, um sie zwischen Terminal und Chipkarte auszutauschen. Eine APDU wird vom Übertragungsprotokoll in eine TPDU (transport protocol data unit) umgewandelt und dann über die serielle Schnittstelle von Terminal bzw. Chipkarte verschickt. APDUs lassen sich in Kommando‐APDU und Antwort‐APDU einteilen.10 API Application Programming Interface. Ein Application Programming Interface ist eine detailliert spezifizierte Softwareschnittstelle innerhalb eines Programms, um einen standardisierten Zugriff auf Funktionen dieses Programms für Dritte zu ermöglichen.10 ASN.1 Die abstract syntax notation one ist eine Beschreibungssprache für Daten. Durch sie lassen sich Daten unabhängig vom benutzenden Computersystem eindeutig definieren und darstellen. ASN.1 ist durch ISO/IEC 8824 und ISO/IEC 8825 definiert.10 BER Die in ASN.1 festgelegten grundlegenden Codierungsregeln BER (Basic Encoding Ru‐ le) dienen dazu, Daten als Datenobjekte zu codieren. BER‐codierte Datenobjekte besit‐ zen ein Kennzeichen (tag), eine Längenangabe (length), den eigentlichen Datenteil (va‐ lue) und optional eine Endkennung. Aus diesem Grund werden sie auch als TLV‐ codierte Daten bezeichnet. Das BER‐Format lässt auch verschachtelte Datenobjekte zu. Eine Untermenge der grundlegenden Codierungsregeln BER sind die DER.10 CBC Cipher Block Chaining Mode. Blockchiffrierung. Der Klartext wird in Blöcke aufgeteilt, die nach einer bitweisen XOR‐Verknüpfung mit dem vorherigen Cyphertextblock ver‐ schlüsselt werden. Da im ersten Schritt noch kein Cyphertextblock vorhanden ist, wird ein zufälliger Initialisierungsvektor verwendet. Handbuch der Chipkarten 10 Jan Keller Carla Schaffner 83 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Plaintext C0 P1 P2 P3 crypt crypt crypt C1 C2 Pn C3 random Cyphertext Abbildung 26: CBC Da durch die Verknüpfung jeder Klartextblock vom vorherigen Geheimtextblock ab‐ hängt, werden Klartextmuster zerstört und die Sicherheit gegenüber dem ECB‐Modus stark erhöht. Als Nachteilig zu erwähnen ist, dass bei einer fehlerhaften Übertragung durch diese Abhängigkeit auch die nachfolgenden Daten unbrauchbar werden. Chosen Ciphertext Attack Bei der „Chosen Ciphertext Attack“ schickt ein Angreifer seinem Opfer ein beliebiges Paket. Das Opfer versucht, diese vermeintlich verschlüsselte Nachricht zu entschlüs‐ seln und reagiert entsprechend darauf. Durch diese Reaktion ist es dem Angreifer möglich, Informationen zu gewinnen um daraus auf gewisse Tatsachen, wie Schlüssel oder Klartext zu schliessen. CryptoAPI Microsoft’s Gegenstück zum RSA Cryptoki API. Cryptoki „Crypto‐key“. Steht für „Cryptographic token interface“. Technologie‐unabhängiges RSA‐API für den Zugriff auf Smartcards. Jan Keller Carla Schaffner 84 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang CT‐API Card Terminal API. Einfachstes Interface für den Zugriff auf Smartcards. Kennt nur drei Funktionen: CT_Init(), CT_Data(), CT_Close(). DER Distinguished Encoding Rule. Untermenge der BER. Im IT‐Security‐Bereich sehr ver‐ breitet. Um die Daten auszulesen wird ein ASN.1 Editor benötigt. Mit einem normalen Texteditor können die Daten nicht gelesen werden. ECB Electronic Codebook Mode. Blockchiffrierung. Der Klartext wird in Blöcke aufgeteilt, die dann einzeln verschlüsselt werden. Plaintext P1 P2 P3 crypt crypt crypt C1 C2 C3 Cyphertext Pn Abbildung 27: ECB Einfachster aber auch unsicherster Blockchiffrierungsmodus. Ein spezifischer Klartext‐ block wird immer auf denselben Geheimtextblock abgebildet, das heisst mit statisti‐ schen Mitteln kann wieder auf den Klartext geschlossen werden. Jan Keller Carla Schaffner 85 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang EMV Europay, Mastercard, Visa. Gemeinsame Spezifikation für Zahlungsverkehrskarten mit Chip sowie dazugehörige Terminals der Firmen Europay, Master Card und Visa. Diese Spezifikationen sind zum weltweiten Industriestandard für Kredit‐, Debit und Börsen‐ karten avanciert und damit das Pendant des Zahlungsverkehrs zur Telekommunikati‐ onsnorm GSM 11.11.10 Hash Als Hash bezeichnet man eine eindeutige Prüfsumme einer Datei oder eines Datensat‐ zes. Mit der zugehörden Hashfunktion können somit Daten auf Ihre Vollständigkeit überprüft werden.11 Headerfile Datei, in der Konstanten, Variablen, Datentypen, Funktionen etc. deklariert werden, um diese in anderen Programmen verwenden zu können. Durch die Deklaration wer‐ den die oben erwähnten Daten nur bekannt gemacht, belegen aber keinen Speicher‐ platz. Eine Header‐Datei kann mit der #include‐Anweisung eingebunden werden. ICC Integrated Circuit Card. Smartcard oder Chipkarte. IFD Interface Device. Physikalische Schnittstelle zwischen PC und Smartcard. Lesegerät. ISO 7816‐4 Kommunikationsprotokoll Kommuniziert mit so genannten APDU’s mit der Smartcard. JCA Java Cryptography Architecture JCE Java Cryptography Extension JDK Java Developer Kit JNI Java Native Interface LDAP Lightweight Directory Access Protocol http://www.informationsarchiv.net/clexid_759.shtml 11 Jan Keller Carla Schaffner 86 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Mask Generation Function MGFs erwarten als Input einen beliebigen String und eine Längenangabe. Daraus pro‐ duzieren sie einen pseudozufälligen Outputstring der gewünschten Länge. MGFs sind deterministisch, das heisst, der Outputstring hängt völlig vom eingegebenen String ab. Der Ein‐ sowie Ausgabestring unterliegt einer Längenbeschränkung, die jedoch sehr gross ist. MD5 Message Digest 5. Generiert aus einer Meldung unbegrenzter Länge einen 128 Bit lan‐ gen Message Digest. Ist im Gegensatz zu SHA‐1 schneller aber weniger sicher. Message Digest Siehe Hash OCF OpenCard Framework. Standard ähnlich PC/SC, jedoch nur für Java. PCMCIA Personal Computer Memory Card International Association. Die PCMCIA‐Karte wur‐ de ursprünglich als Speicherkarte entwickelt. Heute ist sie vielmehr eine Erweite‐ rungskarte, welche vor allem bei Notebooks Verwendung findet, um diese mit Mo‐ dem, ISDN‐Adapter, Netzwerkkarte, USB‐Schnittstellen, FireWire‐Ports oder zusätzli‐ chem Speicher zu erweitern. Die Checkkarten grossen PCMCIA‐Karten werden in drei Typen unterteilt: • Typ I: 3.3mm Dicke • Typ II: 5.5mm Dicke • Typ III: 11mm Dicke Zwei PCMCIA‐Karten des Typs II entsprechen einer Typ III Karte. Standard Notebooks besitzen in der Regel zwei Typ II bzw. einen Typ III Einschub.12 PKCS13 Public Key Cryptography System. Von der Firma RSA Security herausgegebener Stan‐ dard für asymmetrische Verschlüsselungen nach dem Public‐Key‐Prinzip. Beinhaltet RSA‐ und Diffie‐Hellman‐Verfahren. PKCS#1 RSA Cryptography Standard. Empfehlungen für die Implementierung von Public‐Key Kryptographie auf Grundlage des RSA‐Algorithmus. PKCS#3 http://info.pcwebshop.ch/glossar/P.htm http://www.secude.com/services/glossary/p_d.php 12 13 Jan Keller Carla Schaffner 87 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Diffie‐Hellman Key Agreement Standard. Beschreibt Methoden (zum Beispiel den Schlüsselaustausch) im Zusammenhang mit dem Diffie‐Hellman‐Protokoll. PKCS#5 Password‐Based Cryptography Standard. Standards in der Passwort‐basierten Ver‐ schlüsselung (Beispiel DES). PKCS#6 Extended Certificate Syntax Standard. Beschreibt Syntax von unterschriebenen X.509‐ Zertifikaten. PKCS#7 Cryptographic Message Syntax Standard. Spezifiziert ein Format für verschlüsselte oder signierte Nachrichten beziehungsweise Dateien. Grundlage von S/MIME. PKCS#8 Private Key Information Syntax Standard. Format des Private Key und dessen Attribu‐ te. PKCS#9 Selected Attribute Types. Definiert Attributtypen zur Verwendung in den Standards 6, 7 und 8. PKCS#10 Certification Request Syntax Standard. Beschreibt die Syntax eines Certificate Requests an eine Zertifizierungsstelle für einen öffentlichen Schlüssel, einen Namen und eventu‐ ell eine Menge von Attributen. PKCS#11 Cryptographic Token Interface Standard. Spezifiziert eine Schnittstelle namens Cryp‐ toki für Geräte, die kryptographische Informationen enthalten und krypto‐graphische Funktionen ausführen können. PKCS#12 Personal Information Exchange Syntax Standard. Spezifiziert ein portierbares Format zum Speichern oder Transportieren der privaten Schlüssel, Zertifikate und sonstiger Geheimnisse eines Benutzers. PKCS#13 Elliptic Curve Cryptography Standard. In der Entwicklungsphase. Beinhaltet viele As‐ pekte der Elliptische‐Kurven‐Kryptographie, einschließlich Parameter‐ und Schlüssel‐ generierung, Gültigkeitserklärung, digitale Signaturen, Verschlüsselung mit öffentli‐ chen Schlüsseln, Schlüsselvereinbarung und ASN.1‐Syntax. Jan Keller Carla Schaffner 88 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang PKCS#14 Pseudorandom Number Generation Standard. Befasst sich mit der Generierung von Pseudozufallszahlen. PKCS#15 Cryptographic Token Information Format Standard. Soll einen Standard einführen, der es Benutzern ermöglicht, kryptographische Tokens zu benutzen, um sich gegenüber verschiedenen Anwendungen, die diesem Standard entsprechen, zu identifizieren, un‐ abhängig vom Cryptoki oder sonstigen Schnittstellen der Anwendung. PS/2 Personal System 2. Diese, von IBM 1987 auf den Markt gebrachte PC‐Familie, war zu den anderen PC‐Systemen nicht kompatibel und hat sich deshalb auf dem Markt nie durchgesetzt. Schon damals verwendete IBM zum Anschluss der Maus und der Tasta‐ tur den kleinen 8 mm PS/2‐Stecker (daher der Name PS/2). Diese Steckerart ist bei den heutigen PCʹs wieder Standard und wird immer noch mit dem Kürzel ʺPS/2ʺ bezeich‐ net.12 RSA Ein Algorithmus zum Signieren und Verschlüsseln von Informationen. Der RSA‐ Algorithmus ‐ benannt nach seinen Erfindern Rivest, Shamir und Adelman ‐ gilt nach heutigen Maßstäben als sicher und wird unter anderem bei PGP, SSH und HBCI ver‐ wendet. RS‐232 Diese seriellen Anschlüsse eines Computers, auch als ʺCOM‐Portsʺ, als Kommunikati‐ ons‐Anschlüsse, bezeichnet, sind Schnittstellen (9 oder 25‐polig), welche die Daten bitweise (hintereinander, seriell) übertragen und werden häufig zur Verbindung zwei‐ er Rechner per Nullmodem oder zum Anschluss der Maus oder eines Modems ver‐ wendet. Auch V.24 genannt. 12 SHA‐1 Secure Hash Algorithm. Generiert aus einer Meldung von maximal 264 Bits einen 160 Bit langen Message Digest. Ist im Gegensatz zu MD5 sicherer aber langsamer. Shared Objects / Shared Libraries Fast alle Programme unter Unix benötigen eine oder mehrere Libraries, um zu funkti‐ onieren, da ein Teil ihrer Funktionen darin abgelegt sind. Diese Libraries müssen ent‐ weder zur Linkzeit in das ausführbare Programm (Executable) hineinkopiert werden, oder dynamisch zur Laufzeit zum Executable hinzugeladen werden. Jan Keller Carla Schaffner 89 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Libraries, die dynamisch zur Laufzeit geladen werden, nennt man shared Libraries oder shared Objects, da sie gleichzeitig von vielen Programmen benutzt werden kön‐ nen, ohne daß jedes Programm eine private Kopie der Library enthält. Libraries, die zur Linkzeit in das entstehende Executable kopiert werden, heißen stati‐ sche Libraries oder Archiv‐Libraries. 14 Slot Objekt auf einem Token. Jeder Private Key, Public Key oder jedes Zertifikat ist durch einen eigenen Slot ansprechbar. Enthält eine Smartcard beispielsweise 2 Private Keys mit zugehörigem Zertifikat, und noch ein weiteres, unabhängiges Zertifikat, so enthal‐ ten Slot Nummer 1 und 2 je einen Private Key mit Zertifikat und Slot Nummer 3 das unabhängige Zertifikat. OpenSC unterstützt im Gesamten 8 Slots und 4 pro Smartcard Reader. Würde das To‐ ken im oben genannten Beispiel in einen zweiten Reader eingeführt, würden die Slots Nummer 5, 6 und 7 Objekte enthalten. SSL Secure Socket Layer. Technik, mittels der ein Web‐Client den Server authentifizieren kann und der Datenverkehr zwischen beiden verschlüsselt wird. Entwickelt von Net‐ scape und RSA Data Security. Token Objekt, mit dem kryptografische Operationen ausgeführt werden können. USB Universal Serial Bus. Beim immer öfters gehörten Ausdruck USB‐Schnittstelle, handelt es sich um einen neuartigen seriellen Anschluss, über welchen man heutzutage prak‐ tisch alle Peripheriegeräte (Drucker, Scanner, Kamera, Maus, Tastatur, etc.) anschlies‐ sen kann. Natürlich muss das jeweilige Gerät zum Anschluss an eine USB‐Schnittstelle vorgesehen sein. Durch entsprechende Adapter lassen sich auch direkt RS‐232‐, IDE‐ und Geräte mit anderen Schnittstellen an einen USB‐Port anschliessen.12 X.509 Normierung, in der die Struktur von Zertifikaten festgelegt wird http://www.techfak.uni‐bielefeld.de/rechner/sharedlib.html 14 Jan Keller Carla Schaffner 90 24.10.2003 Java Smartcard Unterstützung unter Linux B. Anhang Rückgabewerte PKCS#11 Um die von den PKCS#11‐Methoden zurückgegebene Zahl in einen aussagekräftigen Text umzuwandeln, sind in der untenstehenden Tabellen alle möglichen Werte von CK_RV aufgelistet. Eine mögliche Umwandlungsmethode ist im C‐Quellcode zu fin‐ den. CKR_OK CKR_CANCEL CKR_HOST_MEMORY CKR_SLOT_ID_INVALID CKR_GENERAL_ERROR CKR_FUNCTION_FAILED CKR_ARGUMENTS_BAD CKR_NO_EVENT CKR_NEED_TO_CREATE_THREADS CKR_CANT_LOCK CKR_ATTRIBUTE_READ_ONLY CKR_ATTRIBUTE_SENSITIVE CKR_ATTRIBUTE_TYPE_INVALID CKR_ATTRIBUTE_VALUE_INVALID CKR_DATA_INVALID CKR_DATA_LEN_RANGE CKR_DEVICE_ERROR CKR_DEVICE_MEMORY CKR_DEVICE_REMOVED CKR_ENCRYPTED_DATA_INVALID CKR_ENCRYPTED_DATA_LEN_RANGE CKR_FUNCTION_CANCELED CKR_FUNCTION_NOT_PARALLEL CKR_FUNCTION_NOT_SUPPORTED CKR_KEY_HANDLE_INVALID CKR_KEY_SIZE_RANGE CKR_KEY_TYPE_INCONSISTENT CKR_KEY_NOT_NEEDED CKR_KEY_CHANGED CKR_KEY_NEEDED CKR_KEY_INDIGESTIBLE CKR_KEY_FUNCTION_NOT_PERMITTED CKR_KEY_NOT_WRAPPABLE Jan Keller Carla Schaffner 91 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang CKR_KEY_UNEXTRACTABLE CKR_MECHANISM_INVALID CKR_MECHANISM_PARAM_INVALID CKR_OBJECT_HANDLE_INVALID CKR_OPERATION_ACTIVE CKR_OPERATION_NOT_INITIALIZED CKR_PIN_INCORRECT CKR_PIN_INVALID CKR_PIN_LEN_RANGE CKR_PIN_EXPIRED CKR_PIN_LOCKED CKR_SESSION_CLOSED CKR_SESSION_COUNT CKR_SESSION_HANDLE_INVALID CKR_SESSION_PARALLEL_NOT_SUPPORTED CKR_SESSION_READ_ONLY CKR_SESSION_EXISTS CKR_SESSION_READ_ONLY_EXISTS CKR_SESSION_READ_WRITE_SO_EXISTS CKR_SIGNATURE_INVALID CKR_SIGNATURE_LEN_RANGE CKR_TEMPLATE_INCOMPLETE CKR_TEMPLATE_INCONSISTENT CKR_TOKEN_NOT_PRESENT CKR_TOKEN_NOT_RECOGNIZED CKR_TOKEN_WRITE_PROTECTED CKR_UNWRAPPING_KEY_HANDLE_INVALID CKR_UNWRAPPING_KEY_SIZE_RANGE CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT CKR_USER_ALREADY_LOGGED_IN CKR_USER_NOT_LOGGED_IN CKR_USER_PIN_NOT_INITIALIZED CKR_USER_TYPE_INVALID CKR_USER_ANOTHER_ALREADY_LOGGED_IN CKR_USER_TOO_MANY_TYPES CKR_WRAPPED_KEY_INVALID CKR_WRAPPED_KEY_LEN_RANGE CKR_WRAPPING_KEY_HANDLE_INVALID CKR_WRAPPING_KEY_SIZE_RANGE CKR_WRAPPING_KEY_TYPE_INCONSISTENT CKR_RANDOM_SEED_NOT_SUPPORTED CKR_RANDOM_NO_RNG Jan Keller Carla Schaffner 92 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang CKR_DOMAIN_PARAMS_INVALID CKR_BUFFER_TOO_SMALL CKR_SAVED_STATE_INVALID CKR_INFORMATION_SENSITIVE CKR_STATE_UNSAVEABLE CKR_CRYPTOKI_NOT_INITIALIZED CKR_CRYPTOKI_ALREADY_INITIALIZED CKR_MUTEX_BAD CKR_MUTEX_NOT_LOCKED CKR_VENDOR_DEFINED C. Source Code Der Source Code ist auf der mitgelieferten CD zu finden. D. CD Inhaltsverzeichnis • • • • • • • Beispielanwendung Dokumentation und Abbil‐ dungen J2SDK1.4.1 für Linux Javadoc der erstellten Klassen Der eigentliche Provider und die nötigen Files für die Instal‐ lation des Treibers. Source Coder der erstellten Klassen Testklasse und deren Output Jan Keller Carla Schaffner 93 24.10.2003 Java Smartcard Unterstützung unter Linux E. Anhang Quellenverzeichnis E.1. Bücher Core Java 2 Cay S. Horstmann und Gary Cornell ISBN: 0‐13‐081934‐4 Handbuch der Chipkarten Wolfgang Rankl und Wolfgang Effing ISBN: 3‐446‐22036‐4 C‐Programmierung unter Linux Helmut Herold und Jörg Arndt ISBN: 3‐935922‐08‐6 E.2. Links Newsgroups: news://de.comp.lang.c news://de.comp.lang.java news://comp.lang.c.moderated news://netscape.public.mozilla.crypto news://comp.os.linux.development.apps news://comp.lang.java.security Java http://java.sun.com Java Cryptography Extension (JCE) http://java.sun.com/products/jce/index‐14.html How to Implement a Provider for the Java Cryptography Extension http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/HowToImplAJCEProvider.ht ml Bouncy Castle JCE Provider http://www.bouncycastle.org Wedgetail Java Crypto and Security Implementation http://www.wedgetail.com/jcsi/index.html Jan Keller Carla Schaffner 94 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang PKCS#11 ʺCryptographic Token Interface Standardʺ http://www.rsasecurity.com/rsalabs/pkcs/pkcs‐11/index.html OpenSC Projekt http://www.opensc.org OAEP www.uni‐giessen.de/crypto/kryptoag/ Berichte/crypto01.ps ftp://ftp.rsasecurity.com/pub/rsalabs/rsa_algorithm/rsa‐oaep_spec.pdf PCSC Lite Middleware http://www.linuxnet.com/middle.html http://www.pcscworkgroup.com Cryptoflex Cards Programmerʹs Guide 4.4 http://www.cryptoflex.com/Support/Documentation/documentation.html Smartcards http://www‐t.zhwin.ch/it/snk/pdf/SNK_SmartIF.pdf http://www.wrankl.de http://www.cryptoflex.com SHA‐1 Hashfunktion http://www.itl.nist.gov/fipspubs/fip180‐1.htm MD5 Hashfunktion http://www.ietf.org/rfc.html E.3. Bezugsperson Prof. Dr. Andreas Steffen Technikumstrasse 9 8401 Winterthur +41 52 267 76 77 [email protected] www.zhwin.ch/~sna Jan Keller Carla Schaffner 95 24.10.2003 Java Smartcard Unterstützung unter Linux F. Anhang Installationsanleitung Da der Provider auf dem Betriebssystem Linux Suse 8.2 entwickelt wurde, wird auch die Installation für diese Distribution angegeben. Alle Installationen müssen mit Superuser‐Rechten ausgeführt werden. Bei dieser Anleitung wird davon ausgegangen, dass die Standartinstallation von der CD bereits installiert ist. Ist dies nicht der Fall muss kontrolliert werden, ob die nötigen Installationen oder Deinstallationen bereits getätigt wurden. Zuerst müssen die nötigen Pakete für Java installiert werden. Dazu können im YaST die Pakete java2 und java2‐jre ausgewählt und installiert werden. Abbildung 28: Java Installation Nun sind die nötigen Installationen für den Smartcard Reader und den Provider zu er‐ ledigen: Für das verwendete OpenSC Projekt ist die Installation von openssl‐devel unumgäng‐ lich. Auch dieses Paket wird von SUSE 8.2 zur Verfügung gestellt und kann einfach über YaST installiert werden. Abbildung 29: openssl Installation Jan Keller Carla Schaffner 96 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Weiter ist der alte PC/SC Lite Treiber zu deinstallieren: Abbildung 30: Deinstallation PC/SC Lite Treiber Um die weiteren nötigen Treiber und Module zu installieren, muss das tar‐File jlin_opensc_etc.tar.gz in das gewünschte (zu empfehlen ist: /usr/local/src oder ähnlich) Verzeichnis kopiert und dort entpackt werden. Nach dem Entpacken sind folgende Dateien im Verzeichnis: Abbildung 31: Treiber und Module Nun kann der mitgelieferte, aktuelle Treiber entpackt und installiert werden: tar xvzf pcsc-lite-1.1.1.tar.gz cd pcsc-lite-1.1.1 ./configure make make install Für die Kommunikation mit der Smartcard werden einige PC/SC Tools verwendet. Vorgängig muss das PC/SC Perl Modul installiert werden, da diese Tools auf der Skriptsprache Perl basieren. tar xvzf pcsc-perl-1.1.3.tar.gz cd pcsc-perl-1.1.3 perl Makefile.PL make make install Jan Keller Carla Schaffner 97 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Nun können die eigentlichen PC/SC und OpenSC Tools installiert werden. tar xvzf pcsc-tool-1.2.4.tar.gz cd pcsc-tool-1.2.4 make make install tar xvzf opensc-0.8.0.tar.gz cd opensc-0.8.0 ./configure make make install Konnten diese Installationen ohne Fehler durchgeführt werden, können die Installatio‐ nen für den Provider gemacht werden. Nun muss das File jlin_provider.tar.gz entpackt werden. Somit sind die Files: • JLin.jar • libSCConnection.so • Makefile im Verzeichnis vorhanden. Das Makefile kann mit dem Befehl make ausgeführt werden. Nach dem Ausführen sind folgende Files im Verzeichnis /usr/local/lib/pkcs11/ . Abbildung 32: Benötigte .so‐Files Jan Keller Carla Schaffner 98 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Damit die JVM diese .so‐Files findet, muss der LD_LIBRARY_PATH auf das oben er‐ wähnte Verzeichnis /usr/local/lib/pkcs11/ gesetzt werden. Mit dem Ausführen des Befehls export LD_LIBRARY_PATH=//usr/local/lib/pkcs11 kann diesen gesetzt werden. Wird er Befehl in einer Konsole ausgeführt, ist der Pfad nur für diese eine Konsole gesetzt. Soll der Pfad für alle Benutzer und bereits beim Aufstarten gesetzt werden, kann der obige Befehl im File /etc/profile eingefügt werden. Abbildung 33: LD_LIBRARY_PATH Soll der Provider nun in einer Java Applikation benützt werden, muss das JLin.jar‐File, mit den nötigen .class‐Files, für die Anwendung sichtbar gemacht werden. Um dieses Problem zu lösen, gibt es drei verschiedene Varianten. 1. Es wäre möglich, den CLASSPATH bei jedem Aufruf mitzugeben java –classpath /<da liegt das JLin.jar File>/JLin.jar:. App 2. Um dies nicht jedes Mal aufrufen zu müssen kann die Umgebungsvariable CLASSPATH gesetzt werden. Auch dies wird mit dem Aufruf export CLASSPATH=//<da liegt das JLin.jar File>/JLin.jar:. gemacht, oder wie oben bereits erwähnt im File /etc/profile eingetragen. 3. Die dritte Variante wäre, das JLin.jar in das Verzeichnis <java_home>/jre/lib/ext zu legen. Bei SUSE 8.2 wäre dies der Pfad: /usr/lib/SunJava2‐1.4.1/jre/lib/ext Jan Keller Carla Schaffner 99 24.10.2003 Java Smartcard Unterstützung unter Linux G. Anhang Betriebs‐ / Konfigurationsanleitung Um den KelschaJLin Provider zu benutzen müssen alle Installationen, wie im Anhang F angegeben, korrekt durchgeführt worden sein. Da dieser Provider Services von anderen Providern benützt müssen alle von Java mit‐ gelieferten Provider (SUN, SunJSSE, SunRsaSign, SunJCE, SunJGSS) auch zur Verfü‐ gung gestellt werden. Dies wird normalerweise standardmässig bei der Installation von J2SDK1.4.1 angegeben. Ist dies aus irgendeinem Grund nicht getan, kann dies im File <java_home>/lib/security/java.security angegeben werden. Weitere Informationen dazu siehe Kapitel 10. Damit die Kommunikation mit dem Smartcard Treiber funktioniert muss die Middel‐ ware gestartet werden. Dazu wird der PC/SC Dämon gestartet. Es muss in das Ver‐ zeichnis /usr/local/sbin/ gewechselt werden und dort den Befehl pcscd ausgeführt werden. Damit ist der Dämon gestartet. Somit sind alle nötigen Installationen und Konfigurationen gemacht, um die Java Applikation, die den KelschaJLin Provider benützt zu starten. Im Kapitel 10 ist die Verwendung des KelschaJLin Provider mit seinen Services be‐ schreiben. Auf der CD ist im Verzeichnis des SourceCodes zudem eine Testklasse zu finden, in der die Verwendung des Providers implementiert und auch getestet wurde. Jan Keller Carla Schaffner 100 24.10.2003 Java Smartcard Unterstützung unter Linux H. Anhang Beispielanwendung Zur Verdeutlichung dieses Providers wurde eine kleine Anwendung realisiert, die ei‐ nen Client / Server Login‐Vorgang symbolisiert. Wird die Anwendung ausgeführt, wird ein Fenster mit einem Client‐ und Server‐Gui dargestellt. Abbildung 34: Client‐ / Server‐Gui Um den Login‐Vorgang zu starten muss der Client den Button „Login“ betätigen. So‐ mit beginnt die Applikation alle auf der Smartcard gespeicherten Zertifikate abzuru‐ fen. Diese Zertifikate sind notwendig, damit der Server die Signatur verifizieren kann. Jan Keller Carla Schaffner 101 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Abbildung 35: Randomzahl senden Nachdem der Client den Loging‐Voragang gestartet hat, sendet der Server dem Client, durch die Betätigung des „Send Random“‐Buttons, eine Randomzahl zu. Abbildung 36: Zertifikate und Randomzahl Beim Client wird nun die, vom Server empfangene Randomzahl, dargestellt. Das Gui des Servers zeigt alle vorhandenen Zertifikate. Nun kann der Button „Sign“ betätigt werden. Damit wird ein Gui für die Parameterübergabe des Signierens dargestellt. Jan Keller Carla Schaffner 102 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Abbildung 37: Leeres Parameter‐Gui Nun müssen alle Felder ausgefüllt und ein Hashalgorithmus gesetzt werden. Abbildung 38: Ausgefülltes Parameter‐Gui Ist dies erledigt, kann mit dem Drücken des „Ok“‐ Buttens den Signiervorgang gestar‐ tet werden. Output Abbildung 39: Nach dem Signaturvorgang Im „Output“‐Feld des Clients wird nun die Signatur dargestellt. Durch die Betätigung des Buttens „Verify“ kann die Signatur verifiziert werden. Jan Keller Carla Schaffner 103 24.10.2003 Java Smartcard Unterstützung unter Linux Anhang Abbildung 40: Verification successful War die Verifizierung erfolgreich, wird beim Server „Verification successful.“ ausge‐ geben. Abbildung 41: Verification failed Andernfalls ist im Server‐Gui die Meldung „Verification failed.“ zu sehen. Jan Keller Carla Schaffner 104 24.10.2003