zurück zum Artikel

Cryptography Engineering, Teil 2: AES auf PCs und Servern

Oliver Müller

Die theoretischen Grundlagen zu AES sind bekannt und lassen sich nun in einer ersten praktischen Implementierung anwenden. Dabei soll auch die Zielplattform berücksichtigt werden, denn es gilt, AES in C++ umzusetzen und zu zeigen, wie man eine mathematische Theorie in eine effiziente Computeranwendung wandelt.

Cryptography Engineering, Teil 2: AES auf PCs und Servern

Die theoretischen Grundlagen zu AES sind bekannt und lassen sich nun in einer ersten praktischen Implementierung anwenden. Dabei soll auch die Zielplattform berücksichtigt werden, denn es gilt, AES in C++ umzusetzen und zu zeigen, wie man eine mathematische Theorie in eine effiziente Computeranwendung wandelt.

Cryptography Engineering setzt theoretische Vorarbeiten voraus, wohingegen in anderen Anwendungsdomänen durchaus in Trial-und-Error-Manier "drauflos" programmiert werden kann (aber auch nicht sollte). Bei kryptographischen Systemen ist das schlicht unmöglich. Man muss kein mathematisches Genie oder der ultimative Code-Brecher unter den Kryptanalytikern sein, um kryptographische Algorithmen zu implementieren. Die mathematischen Grundlagen und das Algorithmieren gilt es jedoch zu beherrschen und die Zielplattform im Auge zu behalten. Aber das macht das Cryptography Engineering schließlich so spannend. Nach all der theoretischen Vorarbeit im ersten Teil dieser Artikelreihe [1] soll AES nun praktisch in C++ implementiert werden.

Mehr Infos

Die AES-Funktionen SubBytes(), InvSubBytes(), ShiftRows(), InvShiftRows(), MixColumns() und InvMixColums() operieren alle über der state-Matrix. Es fällt jedoch auf, dass diese Funktionen state wechselnd mit unterschiedlichen Datenbreiten ansprechen. Mal als Byte-Array, mal als Words. Zudem gehen Klartext und Chiffretext in das AES-System als Byte-Stream ein. Das System interpretiert diese Daten je nach Kontext jedoch auch als 32-Bit-Words. Bei der nicht näher bestimmten Zielplattform "32-Bit-Server- und -PC-Systeme" ruft das sofort das alte Problem von Big und Little Endian auf den Plan. Diesem muss eine AES-Implementierung begegnen.

Eine Möglichkeit wäre es, die Implementierung auf Operationen über Bytes herunterzubrechen. Das hätte jedoch den Nachteil, dass der generierte Code aus den 32-Bit-Integer-Rechenwerken der CPUs der Zielplattformen keinen Nutzen ziehen kann. Er würde schlicht Taktzyklen verschwenden. Schließlich wären im Extremfall für Operationen, beispielsweise Shifts, vier einzelne Byte-Operationen statt einer 32-Bit-Word-Operation notwendig.

Mehr Infos

Quellcode

Hinweis: Die Sourcen zu diesem Artikel finden Sie im Tarball auf dem heise Developer FTP [6] zum Download.

Besser ist es, die Reihenfolge der Bytes in einem Word, abhängig von der Endianness des Systems, zu berücksichtigen. Das klingt zunächst nach viel if-else-Blöcken oder umständlichem Umordnen und viel Shifting und Masking zum Zugriff auf die einzelnen Bytes. Da die Beispielimplementierung für diesen Artikel jedoch in C++ erfolgt, lässt sich eine spracheigene komfortable Lösung nutzen. C++ bietet mit dem Datentyp union die Möglichkeit, Daten dem Kontext entsprechend anzusprechen. Ein 32-Bit-Word und seine einzelnen Teilbytes lassen sich elegant wie folgt darstellen (vergleiche Klasse AesEncryption in aes.h):

union word32_t
{
uint32_t w;
struct
{
#ifdef ARCH_BIG_ENDIAN
uint8_t b3;
uint8_t b2;
uint8_t b1;
uint8_t b0;
#else
uint8_t b0;
uint8_t b1;
uint8_t b2;
uint8_t b3;
#endif
};
};

Über die Elementvariable w lässt sich der Wert als 32-Bit-Word auslesen. Über b0 bis b3 lassen sich die einzelnen Bytes ansprechen. Das Präprozessor-Makro ARCH_BIG_ENDIAN bestimmt die Reihenfolge der Bytes – Big oder Little Endian. (Dieses Makro setzt im Übrigen der configure-Prozess unter Unix/Linux. Die Build-Skripte unter Windows, OpenVMS und OS/2 beziehungsweise eComStation setzen das Makro nicht, da sie grundsätzlich Little Endian verwenden.)

Nach dem selben Prinzip deklariert aes.h auch den Datentyp AesEncryption::state_t als union. Damit bildet der Beispielcode den 128-Bit-Block und die State-Matrix ab; letztere dem unteren, in Abbildung 1 gezeigten Teil folgend. Zusätzlich zu den Word-Werten und den geordneten Byte-Werten von b0 bis b15 unterstützt state_t noch das Byte-Array b, um Byte-basierte Operationen in Schleifen zu vereinfachen, bei denen die Reihenfolge der Bytes keine Rolle spielt (siehe AesEncryption::subBytes()).

Diagramm: Das state-Array

Die state-Matrix und das state-Array

Wichtig ist, dass die Elementvariablen einer union keinen zusätzlichen Speicher benötigen. Sie repräsentieren lediglich verschiedene Sichtweisen auf ein- und dieselben Daten.

Das Ganze hat auch einen Nachteil. Statt die eingehenden Klartext- oder Chiffredaten direkt zu verwenden, sind die Daten geordnet in state zu kopieren. "Geordnet" heißt, einzelne Operationen zu erzeugen: state.b0 = data[0], state.b1 = date[1] und so weiter. Eine Schleife lässt sich zum Kopieren nicht nutzen. Zudem sind 16 Einzeloperationen notwendig und das kostet Programmspeicher. Immerhin lassen sich diese 16 Einzeloperationen aber auch als entrollte Schleife auffassen, die in der Regel sogar schneller ist.

Mit diesen Vorüberlegungen ist es ein Leichtes, die Teilfunktionen von AES in der Klasse AesEncryption in aes.cpp zu implementieren. (Die Sourcen liegen im Unterverzeichnis src des Tarballs [7].) Die Methoden subBytes() und invSubBytes() nutzen die inline-Methoden subByte() beziehungsweise invSubByte(), welche die S-Boxen über die Klassenattribute sbox beziehungsweise sboxinv verwenden. Die S-Boxen sind damit als Table-Lookup implementiert, der schnellsten, aber speicherintensivsten Implementierungsvariante. Eine andere Variante soll im nächsten Teil dieser Artikelreihe vorgestellt werden.

Die Implementierung der Methoden shiftRows() und invShiftRows() ist reine Tipparbeit. Die entsprechenden Operationen sind detailliert in [4] beschrieben (PDF [8]). Ebenso verhält es sich mit den Methoden mixColumns() und invMixColumns(). Die verwenden für die "Mixoperationen" über den vier Spalten eines state die Methoden mixColumn() und invMixColumn(). Für ihre Operationen benötigen sie jedoch die Multiplikation in GF(2^8). Eine effiziente Variante wurde bereits im ersten Artikel [9] dieser Reihe vorgestellt. Der entsprechende Algorithmus aus Abbildung 2 ist in der Methode gmul() 1 zu 1 implementiert.

Diagramm: Multiplikation mit xtime()

Die Multiplikation in GF(2^8) mit xtime().

Bleibt zu guter Letzt noch die Methode addRoundKey(), um den Rundenschlüssel zu state zu addieren. Die Methode ist in der Implementierung ebenfalls trivial – sie bildet die notwendigen XOR-Operationen schlicht über den vier 32-Bit-Words aus state und aus dem Rundenschlüssel ab.

Auf dieser Basis implementieren die Methoden encipherState() und decipherState() schließlich die AES-Funktionen Cipher() beziehungsweise InvCipher().

Die Klasse AesEncryption ist so angelegt, dass jede Instanzierung eines Objekts untrennbar mit einem AES-Schlüssel verbunden ist. Die Konstruktoren akzeptieren den AES-Schlüssel als String – entweder als Objekt der C++-Klasse string, oder als C-String als char-Array. Der AES-Schlüssel ist dabei als hexadezimaler Wert als alphanumerischer String in Big-Endian-Notation repräsentiert. Zudem lassen sich die Schlüssel als uint8_t- und uint32_t-Array übergeben. Bei den String-Varianten ermittelt der Konstruktor selbst die AES-Variante – 128, 192 oder 256 Bit – anhand der Länge des übergebenen Strings. Bei den Integer-Arrays ist die Größe des Arrays explizit mit zu übergeben. Anhand dieser Array-Größe schließt der Konstruktor ebenfalls auf die AES-Variante. Werden Strings mit falscher Länge oder falschen Array-Größen übergeben, wirft der Konstruktor die Ausnahme AesBadKeyException.

Anhand der ermittelten Schlüssellänge setzen die Konstruktoren zunächst die Objektattribute knum und rnum, die den Werten Nk und Nr der AES-Spezifikation entsprechen (siehe [4], Seite 7). Anschließend übertragen die Konstruktoren den übergebenen Schlüssel in die unteren Bytes des key-Arrays, das als Objektattribut realisiert ist. Bei den String-Varianten erfolgt das durch die Methode keyHex2Arr(), die zugleich die Konvertierung vom String in Integer-Werte vornimmt. Bei den Integer-Array-Varianten des Konstruktors genügt eine einfache Schleife zum Kopieren der Werte nach key. Im Anschluss übernimmt bei jeder Konstruktorvariante die Methode expandKey() die AES-Key-Expansion. Sie verfügt, im Gegensatz zum in Abbildung 3 gezeigten Ablauf, nur über die zweiten Schleife der Expansion. Die erste Schleife wurde – passend für den Schlüssel als String oder Integer-Array – bereits im Konstruktor ausgeführt.

Diagramm: AES-Key-Expansion

Die AES-Key-Expansion

Ist ein Objekt fehlerfrei instanziiert, ist es fortan untrennbar mit dem betreffenden AES-Schlüssel verbunden. Es repräsentiert ein voll funktionsfähiges Kryptosystem, bestehend aus Schlüssel und Algorithmus.

Mit CppUnit lassen sich diese grundlegenden Algorithmen nun verifizieren. Im Unterverzeichnis tests des Distributions-Tarballs liegen die betreffenden Unit-Tests.

Zunächst ist sicher zu stellen, ob das Konvertieren der Schlüssel aus Strings in das key-Array korrekt funktioniert. Klappt das nicht, kann man sich das Testen der eigentlichen Kryptoalgorithmen sparen – AesConversionTest.cpp enthält die betreffenden Tests. AesConversionTestRunner.cpp beheimatet den Test-Runner, der den Test ausführt. Zunächst erfolgt der Test verschiedener korrekter Schlüssel unterschiedlicher Länge. Anschließend erfolgen noch einige Testläufe mit fehlerhaften Schlüsseln.

In AesAtomicMethodTest.cpp findet der Test der einzelnen AES-Teilfunktionen statt. Als Sollwerte dienen die Operationen aus dem Chiffrebeispiel auf Seite 33 in [4] für den Test. Die Runden 1 bis 9 sowie die erste state-Matrix aus Runde 10 dienen als Referenzdaten. Sie sind als Tabelle in AesAtomicMethodTest::ref als Klassenattribut erfasst. Jede der 46 Zeilen entspricht einem state aus dem Chiffrebeispiel, das der Abbildung~~1 folgend eindimensional "ausgerollt" ist. Gemäß dem Chiffrebeispiel muss die SubBytes-Operation, angewendet auf ref[0], beispielsweise ref[1] ergeben. ShiftRows, angewendet auf ref[1], muss ref[2] ergeben und so fort. Die Tests in den Methoden von AesAtomicMethodTest sind damit weitestgehend selbst erklärend.

Bis zu diesem Punkt haben die Test einige (nicht repräsentative) Fälle durchlaufen. "Grobe Schnitzer" in der Implementierung decken diese sicherlich auf.

Nur die grundlegenden Methoden encipherState() und decipherState() implementieren jeweils die AES-Funktionen Cipher() und InvCipher(). Sie operieren nur über den fixen Blöcken von 128 Bit. Um nun einen vollständigen Chiffrieralgorithmus für beliebig lange Nachrichten zu erhalten, sind diese grundlegenden Methoden in umfassendere Methoden einzubetten. Einige solcher Bespiele sind die öffentlichen Methoden encipher*() und decipher*() in AesEncryption. Sie unterscheiden sich darin, welche Form von Eingabe (String, Vektor, Array) und welche Ausgabe (String, Vektor) sie erzeugen.

Grundsätzlich ist die Arbeitsweise der Methoden dieselbe. Beim Verschlüsseln füllen sie Nachrichten mit einer Länge, die kein Vielfaches von 16 (128-Bit-Block!) sind, mit Nullbytes auf die nächste 16er-Grenze auf. Anschließend wird die Nachricht Block für Block verarbeitet. Hierbei wird zunächst ein state befüllt, dieser mit encipherState() verschlüsselt und anschließend das Ergebnis in das Rückgabeobjekt geschrieben. Beim Entschlüsseln erfolgt das im Wesentlichen nach dem gleichen Schema, das Auffüllen mit Nullbytes entfällt hier.

Der Codeblock zum Ent- und Verschlüsseln in den Methoden besteht aus einem auffälligen switch, der die einzelnen Betriebsmodi der Chiffrierung unterscheidet. Das hier gezeigte Beispiel unterstützt die typischen Modi Electronic Code Book (ECB), Cipher Block Chaining (CBC), Cipher Feedback (CFB) und Output Feedback (OFB). Nähere Beschreibungen zu diesen Modi finden sich in [1] und [5] beziehungsweise bei Wikipedia ([6], [7], [8] und [9]). [5] enthält zudem weitere, hier im Code nicht implementierte Modi. Zudem geht [5] auf die Wahl des passenden Chiffriermodus ein.

Außer dem einfachen ECB benötigen CBC, CFB und OFB für ihren Betrieb noch einen Initialisierungsvektor (IV), um die Methoden setIvFrom*() zu setzen. Der Initialisierungsvektor ist nichts anderes als ein zusätzlicher 128-Bit-Block. Nähere Informationen enthalten die oben genannten Beschreibungen zu den Modi.

Die restlichen Methoden von AesEncryption dienen der Konvertierung beziehungsweise zur Ausgabe von Daten. Bleibt nun noch ein verbindlicher Abnahmetest. Auch dafür kann man mit CppUnit als Klasse AesAlgorithmTest gestalten. Für den Test verwendet man die offiziellen Testvektoren des National Institute of Standards (NIST). Diese sind eine Menge von bekannten Kryptogrammen für einen gegebenen Klartext und Schlüssel und sind als Known Answer Test (KAT) bekannt. Über die Seite des NIST können sie heruntergeladen werden (ZIP-Datei [10]). Exakt diese Testvektoren des KAT liegen als Klassenattribut kat der Klasse AesAlgorithmTest bei. Da die Vektoren sehr umfangreich sind, ist das Array vom Typ AesAlgorithmTest::KatVector in der Datei kat.cpp des Beispielcodes ausgelagert. Die Testvektoren ziehen die Klasse AesAlgorithmTest heran, um einen umfangreichen und standardisierten Test über die Beispielimplementierung durchzuführen. Wie die Datei COMPATIBILITY ausweist, waren die Tests auf einer Vielzahl von Plattformen, 32- wie 64-Bit-Systeme mit Big- und Little-Endian-CPUs, erfolgreich. Der Code entspricht somit der Spezifikation von AES.

Die Beispielimplementierung ist auf einer breiten Palette von Zielsystemen lauffähig. Der Build auf Unix und Unix-ähnlichen Systemen kann durch Verwendung der GNU Autotools erfolgen. Der Code ist auf den klassischen Unix-Derivaten, wie AIX, HP/UX, Tru64 UNIX, (Open)Solaris und BSD, sowie Linux und GNU/Hurd ebenso lauffähig wie auf Betriebssystemen mit POSIX/UNIX-Addons wie dem Mainframe mit z/OS UNIX System Services und Windows mit Cygwin. Zusätzlich lässt sich das Beispiel durch separate Build-Skripte unter Windows mit Visual Studio, unter OpenVMS mit HP C++ und sogar unter OS/2 beziehungsweise eComStation mit OpenWatcom kompilieren und linken. Näheres zum Build auf den jeweiligen Plattformen findet sich in der Datei README des Distributions-Tarballs.

Auf jedem – entweder per GNU Autotools oder separatem Build-Skript – unterstützten System lässt sich in jedem Fall das Beispielprogramm aes32bit kompilieren und linken. Das Kommandozeilenprogramm füllt die AES-Implementierung mit Leben. aes32bit findet sich nach dem Build im Unterverzeichnis src der entpackten Distribution.

Das Programm unterscheidet zwischen zwei Modi: Textmodus und Binärmodus. Im Textmodus liest die Anwendung beim Verschlüsseln Zeilen von cin. Diese Zeilen werden bei Bedarf mit Nullzeichen auf die 16-Byte-Grenze aufgefüllt, verschlüsselt und das Kryptogramm als hexadezimaler String auf cout ausgegeben. Beim Entschlüsseln liest die Anwendung Kryptogramme als hexadezimale Strings über cin ein, entschlüsselt diese und gibt die so erhaltenen Strings auf cout aus. Ein einfacher Test dieses Modus lässt sich in der Unix-Shell wie folgt erreichen:

./aes32bit -ek 00112233445566778899aabbccddeeff | ./aes32bit -dk 00112233445566778899aabbccddeeff

oder unter Windows und OS/2 beziehungsweise eComStation in der Eingabeaufforderung:

aes32bit.exe -ek 00112233445566778899aabbccddeeff | aes32bit.exe -dk 00112233445566778899aabbccddeeff

oder unter OpenVMS in der DCL-Kommandozeile, wenn aes32bit als Command-Verb definiert ist:

define/user sys$output crypto.txt
aes32bit -ek 00112233445566778899aabbccddeeff
define/user sys$input crypto.txt
aes32bit -dk 00112233445566778899aabbccddeeff
delete crypto.txt;*

Eine direkte Pipe führt unter dem DCL des OpenVMS leider zu einem Stackdump. Alternativ lässt sich jedoch die Unix-Shell der GNV-Umgebung nutzen, um das obige Unix-Pipe-Kommando auch unter OpenVMS auszuführen.

Über das Flag -k erhält aes32bit den AES-Schlüssel als hexadezimalen Wert. In den Beispielen kommt ein 128-Bit-Schlüssel zum Einsatz. -e und -d schalten das Programm in den Ver- beziehungsweise Entschlüsselungsmodus. Alle Eingaben, die man jetzt auf der Standardeingabe auf den ersten Prozess schickt, verschlüsselt dieser und schickt das Kryptogramm in die Pipe. Der zweite Prozess erhält das Kryptogramm über die Pipe, entschlüsselt es wieder und gibt den Klartext aus. Die Ausgabe ist unspektakulär und wirkt wie ein simples Echo, zeigt jedoch, dass das Programm funktioniert. Man merkt das, wenn man den Schlüssel auf der einen oder anderen Seite der Pipe ändert, denn dann erhält man kryptische Zeichen, da die Entschlüsselung mit dem falschen Schlüssel erfolgt.

Das scheinbare Echo ist in Wahrheit keines. Vergleicht man die Ausgaben mit Eingaben, gibt es Differenzen. Die sind beim Entschlüsseln des Kryptogramms auf das Auffüllen mit Nullbytes, um die Blocklänge zu erreichen, zurückzuführen. Die angehängten Nullbytes sind auch in der Ausgabe vorhanden.

Höchst unwillkommen ist es, Dateien über den Textmodus zu verschlüsseln, denn beim Entschlüsseln würden abweichende Dateien entstehen. Gerade bei binären Daten führt dies zu unbrauchbaren Dateien. Daher unterstützt das Beispiel auch einen binären Modus, der beim Verschlüsseln keine einzelnen Zeilen liest, sondern 128-Bit-Blöcke. Die verschlüsselt das Programm Block für Block. Beim Entschlüsseln entsteht damit wieder dasselbe Abbild; ebenfalls Block für Block. Lediglich der letzte Block der Datei ist kritisch. Er enthält – durch das notwendige Auffüllen mit (Null-)Bytes – mehr Daten als die ursprüngliche Datei. aes32bit fügt daher noch einen weiteren Block an die Ausgabe an, der festhält, wie viele Bytes der letzte (zur Datei gehörende) Block enthielt. Mit Hilfe dieser Option lässt sich beim Entschlüsseln auch die Länge der Datei rekonstruieren und damit ein exaktes Ebenbild der ursprünglichen Datei erzeugen.

Mit Hilfe der Option -b lässt sich der Binärmodus zuschalten. Die Eingabe kann hier mittels -f aus einer Datei lesen und die Ausgabe durch -o in eine Datei schreiben. Zusätzlich finden sich noch diverse Optionen zum Einstellen des Betriebsmodus und zum Setzen des IV bei aes32bit. Eine kurze Hilfe gibt das Programm aus, wenn entweder gar keine Argumente übergeben werden, oder -h in der Kommandozeile vorhanden ist.

Der Build kann mit oder ohne CppUnit erfolgen. Auf manchen Plattformen, auf denen kein CppUnit zur Verfügung steht und eine Portierung für diesen Beitrag unverhältnismäßig wäre, ist ein Build grundsätzlich nur ohne CppUnit möglich. Hierzu zählen beispielsweise OpenVMS und OS/2 beziehungsweise eComStation. Auf Betriebssystemen, auf denen CppUnit verfügbar und installiert ist, lassen sich folgende Testprogramme erstellen:

Alle drei Programme finden sich nach dem Build im Unterverzeichnis tests und erwarten keinerlei Argumente auf der Kommandozeile.

Das Beispiel und die CppUnit-Tests zeigen, dass die AES-Implementierung auf einer Vielzahl unterschiedlicher Systeme spezifikationskonform funktioniert. Allerdings ist das für den Einsatz in der realen Welt vielfach nicht ausreichend. Abseits der Kryptografie lauern noch einige Gefahren, die der "Cryptography Engineer" umschiffen muss.

Erstes markantes Problem des gezeigten Beispielprogramms: Es empfängt den Schlüssel über die Kommandozeile. Leider ist die Kommandozeile eines Prozesses auf vielen Systemen, allen voran Unix und Windows, für alle Benutzer einsehbar. Auch andere Systeme wie z/OS und BS2000/OSD sind durch ihre POSIX/Unix-Subsysteme inzwischen in diesem Punkt "verwässert" worden. Ein interner Angreifer muss also beispielsweise unter Unix nur ein geeignetes ps-Kommando absetzen, um den Schlüssel zu ermitteln. Schlüssel, ebenso wie Passwörter, sind daher aus der Kommandozeile zu verbannen.

Andererseits stellt sich dann die Frage nach der sicheren Ablage von Schlüsseln. Diese Frage des Key-Managements ist ebenso wichtig wie die korrekte Implementierung des kryptografischen Algorithmus selbst. Das Thema würde aber den Rahmen dieses Beitrags bei weitem sprengen. Einen ersten Einblick in die Thematik bietet [10].

Ein anderer Punkt, der auch teilweise die AES-Implementierung als solche betrifft, ist der Umgang mit Schlüsseln und Daten im Speicher. Schlüssel wie Daten sind im Hauptspeicher sofort zu vernichten, nachdem sie nicht mehr benötigt werden. Andernfalls steigt das inhärente Risiko, dass die Daten beispielsweise im Falle eines Programm- oder Systemcrashs (Core-Dump) ausgespäht werden können. Das Überschreiben mit Zufallsdaten ist ein geeigneter Weg.

Dies wirft jedoch viele Fragen zum Umgang mit Daten im Betriebssystem auf. Was ist mit ausgelagerten Daten im Swap? Insbesondere im Falle eines Systemcrashs? Hierzu finden sich erste Antworten, aber auch offene Fragen in [10].

Abseits der reinen Kryptografie und ihrer Implementierung in Software warten also noch viele weitere Themen auf dem Weg zum sicheren Programm. Mit dem vorgestellten Beispiel wurde der weite Weg von der Mathematik zur auf vielen unterschiedlichen Plattformen lauffähigen AES-Implementierung vorgestellt. Auch wenn es im Programm an sich nur noch um das Rechnen und nicht mehr um das mathematische Beweisen geht, bleibt die Umsetzung höchst anspruchsvoll. Selbst auf einer vertrauten Zielumgebung, wie Unix oder Windows, gilt es doch eine Reihe von Details zu beachten. Die effiziente Umsetzung der Multiplikation in GF(2^8) ist ein Beispiel für direkt angewandte Mathematik. Obwohl in einer Hochsprache programmiert wird, müssen dennoch hardwarenahe Details, wie die Endianess des Systems, im Auge behalten werden.

Die Hardware wird im nächsten Teil dieser Artikelreihe eine größere Rolle spielen. Dann soll es weg von den großen Server- und Workstationsystemen und hin zu den Winzlingen der Computersysteme gehen – um AES auf 8-Bit-Mikrocontrollern.

Oliver Müller
ist freiberuflicher IT-Berater und -Trainer mit den Schwerpunkten Software Engineering, Kryptografie, Java EE, Linux, Unix, z/OS und OpenVMS. Er ist unter info at oliver-mueller.com zu erreichen.

Mehr Infos

Referenzen

[1] Buchmann, Johannes:
Einführung in die Kryptographie.
Berlin, Heidelberg: Springer 3. Auflage 2004
[2] Menezes, Alfred J. / Oorschot, Paul van / Vanstone, Scott:
Handbook of Applied Cryptography.
Boca Raton (FL): CRC Press 1997
[3] Hankerson, Darrel / Menezes, Alfred J. / Vanstone, Scott:
Guide to Elliptic Curve Cryptography.
New York: Springer 2004
[4] National Institute of Standards (Hrsg.):
Announcing the ADVANCED ENCRYPTION STANDARD (AES).
Federal Information Processing Standards Publication 197: November 26, 2001
URL: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf [11]
[Stand: 18.05.2011]
[5] Schneier, Bruce:
Angewandte Kryptographie - Protokolle, Algorithmen und Sourcecodes in C.
Bonn: Addison-Wesley 1996
[6] Wikipedia (Hrsg.):
Electronic Code Book Mode.
URL: http://de.wikipedia.org/wiki/Electronic_Code_Book_Mode [12]
[Stand: 18.05.2011]
[7] Wikipedia (Hrsg.):
Cipher Block Chaining Mode.
URL: http://de.wikipedia.org/wiki/Cipher_Block_Chaining [13]
[Stand: 18.05.2011]
[8] Wikipedia (Hrsg.):
Cipher Feedback Mode.
URL: http://de.wikipedia.org/wiki/Cipher_Feedback_Mode [14]
[Stand: 18.05.2011]
[9] Wikipedia (Hrsg.):
Output Feedback Mode.
URL: http://de.wikipedia.org/wiki/OFB [15]
[Stand: 18.05.2011]
[10]Ferguson, Neal / Schneier, Bruce / Kohno, Tadayoshi:
Cryptography Engineering - Design Principles and Practical Application.
Indianapolis (IN): Wiley Publishing 2010

(rl [16])


URL dieses Artikels:
https://www.heise.de/-1375774

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/Cryptography-Engineering-Teil-1-Zur-Theorie-des-Advanced-Encryption-Standard-1350362.html
[2] https://www.heise.de/hintergrund/Cryptography-Engineering-Teil-1-Zur-Theorie-des-Advanced-Encryption-Standard-1350362.html
[3] https://www.heise.de/hintergrund/Cryptography-Engineering-Teil-3-AES-auf-8-Bit-Mikrocontrollern-1436872.html
[4] https://www.heise.de/ratgeber/Cryptography-Engineering-Teil-4-AES-auf-AVR-ATmega-1442338.html
[5] https://www.heise.de/ratgeber/Cryptography-Engineering-Teil-5-AES-Implementierung-fuer-mobile-Endgeraete-1659321.html
[6] ftp://ftp.heise.de/pub/ix/developer/mueller_aes32bit-1.00.tar.gz
[7] ftp://ftp.heise.de/pub/ix/developer/mueller_aes32bit-1.00.tar.gz
[8] http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
[9] https://www.heise.de/hintergrund/Cryptography-Engineering-Teil-1-Zur-Theorie-des-Advanced-Encryption-Standard-1350362.html
[10] http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
[11] http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
[12] http://de.wikipedia.org/wiki/Electronic_Code_Book_Mode
[13] http://de.wikipedia.org/wiki/Cipher_Block_Chaining
[14] http://de.wikipedia.org/wiki/Cipher_Feedback_Mode
[15] http://de.wikipedia.org/wiki/OFB
[16] mailto:rl@ix.de