 Willkommen am dritten Tag der GPN zum ersten Vortrag hier im Mediencenter. Alex Marvel, Max erarbeitet beim Security Team bei ETERATEK und beschäftigt sich dich dort mit Sicherheitstests, Bedrohungsanalysen und Architekturreviews für Softwareprojekte. Dort bastelt er an der OVOS Securebox mit und hat vorher an der TU Dammstadt promoviert und erforscht, wie man Menschen dazu bringt, ihre Webseiten weniger kaputt zu machen. Willkommen, viel Spaß beim Vortrag, wie man mit Mathematik eine API übernehmen kann und wie gute Architektur das verhindert. Willkommen. Ja, moin moin. Schön, dass ihr alle da seid, so quasi mitten in der Nacht auf der GPN, morgens um 10 Uhr. Genau. Also moin, ich bin Max und wie eben gerade schon gesagt wurde, ich mache was mit Security bei ETERATEK und habe vorher was mit Security und Menschen an der TU Dammstadt gemacht und möchte damit beschäftigt, wie man irgendwie Leute davon überzeugt, dass es vielleicht eine gute Idee wäre, die Sicherheitslücken von ihrer Webseite runterzunehmen. Das ist manchmal schwieriger als man denkt. Zeug, von dem ihr vielleicht schon mal gehört habt, an dem ich mitgearbeitet habe, ist privacyscore.org, privacymail.info, das inzwischen offline, weil es nicht mehr funktioniert hat und eben die Securecodebox. Ich mag Kryptografie und ich mag interessante Fehler, aus denen man was lernen kann und an dieser Stelle kam tatsächlich in einem Kundenprojekt zwei Sachen zusammen und da wollte ich euch einmal kurz von berichten. Wir reden hier über ein relativ einfache Web-Application. Das heißt, wir haben irgendwie was, das läuft in dem Browser beim User. Das redet mit dem Backend vor Frontend, der im Endeffekt nur dafür da ist, den User einmal kurz zu authentifizieren und eben auch alle Autorisierungschecks zu machen, die man so machen muss. Und das Backend vor Frontend redet dann wiederum mit einem AP Gateway, hat dafür so ein Schlüssel, mit dem es mit dem reden kann. Das AP Gateway redet dann mit einem Haufen Microservice dahinter. Und das ist so eine Anwendung, die bei so einem Finanzdienstleister war, um so nachzugucken, was ist der aktuelle Stand von einer Abwicklung, was gibt es da vielleicht auch für Rechnungen, die damit zusammenhängen, was hat der Kunde uns vielleicht noch geschickt, hat er vielleicht gesagt, ich kann das jetzt nicht zahlen, aber vielleicht in zwei Wochen oder so. Das findet man dann alles über dieses System. Das netter an der Architektur hier ist, dass man jetzt einfach sagen kann, gut, wir setzen noch der Firewall ein. Die war in diesem Fall zwischen dem AP Gateway und den Services. Das heißt, man konnte nicht direkt mit den Services reden, sondern nur mit dem AP Gateway. So, wie gut diese Idee ist, da kommen wir später noch zu. Im Rahmen von dem Mini-Pen-Test, den wir gemacht haben, ging es um die Anwendung und das Backend for Frontend. Die ganzen anderen Teile dahinter waren eigentlich out of scope, hatten wir dann schon mit anderen Checks abgedeckt. So, ich zeige euch jetzt einmal ein spezifisches Feature von dieser Plattform. Und das ist eben, dass man sich einen bestimmten Prozess angucken kann. Das heißt, ich kann jetzt sagen, okay, hier gab es nur bestimmte Rechnungen, die gestellt wurde oder so. Gibt mir doch mal die Details dazu. Dann geht also der Browser zum Backend for Frontend und sagt, hey, gib mir doch mal die Infos zu diesem Prozess. Das Backend for Frontend weiß natürlich selber nix, sondern geht dann zum AP Gateway und sagt, hallo, ich bin das Backend for Frontend, hier ist mein API Key, bitte gib mir doch mal die Informationen und kriegt halt ein Haufen Daten zurück. Als Teil von diesen Daten sind auch Download Links mit dabei für Dateien. Diese Download Links zeigen jetzt aber auf das AP Gateway. Das hilft natürlich dem User nicht so richtig viel, weil der kann sich ja gar nicht beim AP Gateway authentifizieren. Das heißt, diese Anfrage muss durch das Backend for Frontend gehen. Was die Entwickler sich da also jetzt gedacht haben, ist ja super. Wir verschlüsseln einfach diesen Download Link, weil wenn man den einfach im Plain Text behalten würde, dann könnte man den ja ändern. Das wäre dann irgendwie so server-side-request-forgery und solche unschönen Dinge, die dann möglich werden. Damit wollen wir uns nicht abgeben. Deswegen verschlüsseln wir das einfach. Kann nix mehr passieren. Geben die verschlüsselten Daten zum Client. Und wenn der Client das runterladen will, dann sagt er, hallo, gib mir mal bitte den Download mit diesem verschlüsselten Blob. Auf den Server wird es entschlüsselt. Dann wird die resultierende URL abgefragt, wieder mit dem AP Key, damit man eben an die Datei herankommt. Die Datei kommt zurück und wird an den User zurückgegeben. Das war also so grob der Ablauf in diesem Feature. Netterweise war das jetzt ein Whitebox Test. Das heißt, wir konnten uns tatsächlich auch den Source Code angucken. Ich habe jetzt hier mal so eine Reimplementation-Grope von dem, was ich da gesehen habe gebaut. Das sieht ungefähr so aus. Am Anfang holen wir uns 16 Random Bites für einen sogenannten Initialisierungsvektor. Was das ist, kommen wir gleich zu. Dann sagen wir, okay, ich möchte gerne etwas verschlüsseln, mit AES128 im Cipherblock chaining Modus unter einem bestimmten Key, der auf dem Server liegt. Man verschlüsselt den ganzen Kram und am Ende gibt man eben diesen Initialisierungsvektor und den Ciphertext zurück. So, relativ simple Verschlüsselungsfunktion. Da ich nicht weiß, wie all euer Hintergrund ist und ich auch gesagt habe, ich hole euch da ganz am Anfang ab, jetzt einmal ganz kurzer Primer zum Thema Blog-Ciphers. Was ist eigentlich eine Blog-Cypher? Eine Blog-Cypher ist eine sogenannte symmetrische Verschlüsselungsfunktion. Das heißt also, die Daten werden mit dem gleichen Schlüssel verschlüsselt und entschlüsselt, nicht so wie bei zum Beispiel PGB oder so, wo es ein Public Key und ein Private Key gibt. Eine Eigenschaft von diesen Blog-Ciphers ist, dass die eine bestimmte Input-Größe haben, in diesem Fall 16-Bite. So, das heißt, wenn ich jetzt einfach nur 16-Bite verschlüsseln möchte, dann ist das relativ einfach. Ich nehme diesen plaintext, ich packe den in die Verschlüsselungsfunktion mit dem Key, bekomme den Ciphertext raus, bin fertig. Die meisten interessanten Dinge in dieser Welt sind aber mehr als 16-Bite lang. Und dann passieren halt so merkwürdige Dinge, weil jetzt die naive Variante jetzt weiterzumachen wäre halt zu sagen, okay cool. Ich splitter das jetzt in Blocks von 16-Bite, verschlüssel jeden einzelnen Block unter dem gleichen Key, habe dann jeweils den Ciphertext. So, nennt sich Electronic Code Book Modus. Das ist leider eine schlechte Idee, denn wenn man jetzt hier dreimal den gleichen plaintext-Block reingibt, kommt auch dreimal der gleiche Ciphertext raus. Ihr kennt vielleicht dieses recht berühmte Bild in dieser Welt, wo man eben sehen kann, da kann man immer noch Strukturen erkennen in dem ECB-verschlüsselten Daten, weil eben gleicher Input, gleicher Output. Jetzt versteht ihr auch den Witz auf meinem T-Shirt. Genau, das ist also eine schlechte Idee. Wir wollen was anderes machen. Und um das zu verstehen, jetzt nochmal ganz kurz zurück ins erste Semester Informatik, was ist Exclusive Or? Eine Operation, die man auf Bits macht. Das heißt, wenn ich das Exclusive Or zwischen zum Beispiel einer 1 und einer 1 nehme, dann kommt eine 0 raus und im Endeffekt sagt dieses Exclusive Or einfach nur, wenn beide Inputs gleich sind, ist das Ergebnis 0 und wenn die beiden Inputs unterschiedlich sind, ist das Ergebnis 1. Das ist ziemlich praktisch in der Kryptografie, denn das hat die Eigenschaft, dass wenn man sagt, ich X-Ore irgendwas mit sich selber, dann streicht sich das raus, weil alle Bits sind gleich, das heißt, alle Bits sind 0 danach. Das heißt, X, XOR, Y, XOR, X ergibt Y, das kürzt sich raus. So, das ist alles, was ihr über XOR wissen müsst. Und damit können wir jetzt weitergehen und können sagen, was ist eigentlich Cyberblock chaining? Hat nichts mit Bitcoin zu tun, Gott sei Dank, sondern ist ein Verschlüsselungsmodus, wo wir im Endeffekt sagen, wir wollen nicht, dass wir immer den gleichen Output hier unten rausbekommen, wenn der Input oben gleich ist. Deswegen nehmen wir, bevor wir diesen Input verschlüsseln, noch den Cyphertext vom vorherigen Block und XOR den auf den Pläntext drauf. Dadurch kommt jetzt hier unten ein anderer Cyphertext raus, weil es hier rausgekommen ist, weil eben auch ein anderer Input reingegangen ist. Wenn ich das entschlüsseln will, mache ich das Ganze eben umgekehrt. Ich nehme sozusagen den Cyphertext vom vorherigen und XOR den nach der Entschlüsselung hier wieder drauf und bekomme wieder den gleichen Pläntext. Jetzt ist natürlich noch die Frage, wenn ich den vorherigen Block nehmen will, was mache ich denn mit dem ersten Block? Da kommt dieser Initialisierungsvektor rein. Das heißt, da wird man einfach nur 16 zufällige Bytes in diesem Fall und XOR die auf dem Pläntext drauf, damit eben auch der erste Block sozusagen nicht irgendwelche Muster verrät. Heißt auch, ich muss diesen Initialisierungsvektor irgendwie mit dem Cyphertext zusammen transportieren. Das haben wir eben im Code auch gesehen, dass da sozusagen ein Initialisierungsvektor, ein Separator und dann der tatsächliche Cyphertext kam. So, genau. Ich schreibe euch das jetzt nochmal kurz hier in der mathematischen Notation eher so hin. Das sagt im Endeffekt genau das Gleiche. Das sagt einfach nur, wenn ich den Cyphertext des nullten Blocks haben möchte, dann verschlüssel ich den nullten Block GXOR mit dem Initialisierungsvektor und ansonsten eben mit dem Cyphertext vom vorherigen Block für alle weiteren Blöcke. Entschlüsselung sieht auch so aus und zur Erinnerung nochmal diese Eigenschaft von der bulschen Logik. So, jetzt haben wir schon alles, was wir brauchen, um diesen Angriff zu konstruieren. Ich fasse nochmal kurz zusammen, was wir jetzt wissen. Wir wissen, die Anwendung verschlüsselt eine URL. Das wissen wir zum einen, weil wir den Source Code gesehen haben. Zum anderen wissen wir es auch, weil es eigentlich nicht groß anders sein kann in so einem Kontext. Wir wissen auch grob, wie diese URL aussieht, weil an einer anderen Stelle kam mal eine Federmeldung, wo so eine URL vom API Gateway angezeigt wurde. Das heißt, das würden wir sogar als Angreifer wissen. Wir wissen auch, dass das System IS im Cypherblock Chaining ohne Authentifizierung des Cyphertextes verwendet. Und ja, wir wissen auch, dass natürlich die Anwendung hinterher einen Get auf diese entschlüsselte URL machen muss, um an dieses Dokument heranzukommen. An diesem Get hängt dann wiederum ein Token dran, das Rechte auf dem API Gateway hat. Und natürlich wissen wir auch, dass wir beliebige Daten an diesen Download Endpoint schicken können, weil es ja ein öffentlicher Endpoint ist. So, kann ich erstmal hinschicken, was ich will, muss der Server mit klarkommen. So, das ist eigentlich alles, was wir brauchen. Der Angriff, den wir jetzt ausführen werden, der nennt sich im Englischen malleable encryption. Im Deutschen heißt das sowas wie veränderliche Verschlüsselung. Das bedeutet im Endeffekt, ich habe einen Cyphertext und ich habe den dazugehörigen Initialisierungsvektor und ich weiß, wie der erste Block des plaintextes aussieht. Wissen wir ja, hatten wir gerade gesagt, wir wissen, wie die URLs aussehen. Und mit diesem Wissen ist mein Ziel, dass ich den Cyphertext und oder den Initialisierungsvektor so abändere, dass bei der Entschlüsselung einen von uns bestimmter neuer plaintext für den ersten Block herauskommt, den wir uns aussuchen können. So, wie funktioniert das Ganze? Na ja, der Ansatz ist jetzt erstmal, ich sage okay, ich weiß, was der tatsächliche plaintext ist, der da verschlüsselt ist für den ersten Block und ich weiß, was ich möchte, was da steht. Das ist was anderes, das nennt wir hier, also p0 ist der tatsächliche plaintext, p0 ist das, was wir möchten, das rauskommt. Wir berechnen jetzt erstmal den xor zwischen diesen beiden Sachen und nennen das d, damit wir es irgendwie wiedererkennen später, d für Differenz. Dann berechnen wir einen neuen Initialisierungsvektor, indem wir den alten Initialisierungsvektor mit diesem d nochmal xorren und dann senden wir einfach den unveränderten Cyphertext und den veränderten Initialisierungsvektor an den Server. So, was genau macht jetzt der Server? Na ja, der Server geht los und sagt, ich möchte das gerne jetzt entschlüsseln. Was ist mein erster plaintext Block? Sagt okay, gut, ich entschlüssel den Cyphertext und xor das mit dem IV, Initialisierungsvektor, den der Kleint mir gerade gegeben hat. Das ist IV Strich hier. So, beim entschlüsseln, sagt er jetzt natürlich erstmal gut hier, das ist irgendwie, die Entschlüsselung ist der Original plaintext gexort mit dem Original IV. Wenn hier jetzt auch wieder der Original IV stehen würde, weil wir ihn nicht verändert hätten, dann würden sich die beiden hier rausstreichen. Man hätte p0 den alten plaintext und wir wären fertig. Wir haben es jetzt aber verändert. Das heißt, jetzt lösen wir nochmal kurz auf, was war nochmal IV Strich? Na ja IV Strich ist eigentlich nur IV xord d und was war nochmal d? Stimmt, d war irgendwie p0 xor p0 Strich. So, jetzt guckt man da drauf und sagt sich, warte mal, da kann ich eine ganze Menge rauskürzen. Irgendwie die beiden IVs kürzen sich raus und die beiden Original plaintexte kürzen sich raus. Bleibt über der plaintext, den wir uns ausgesucht haben. So und das ist eigentlich schon alles, was wir hier machen müssen. Das Schöne ist jetzt, wir haben die Kontrolle über die ersten 16 Beide des plaintexts von der URL. Das ist hier der rot markierte Teil. Das reicht, um dann andere Domain reinzuschreiben, wenn die kurz genug ist und da heutzutage Domains ja nicht viel kosten, habe ich mir die einfach mal registriert und an meine IP weitergeleitet, mal einen Listener aufgemacht und zack. So, das heißt, ich habe jetzt eine Anfrage bekommen auf meinen Laptop von dem Backend for Frontend, das mir freundlicherweise den Authentifizierungskey für das API Gateway mitgeliefert hat. So, das heißt, jetzt gucken wir mal, das ist die eigentliche Architektur, was wir jetzt gemacht haben ist so. Jetzt habe ich hier den Key und das Schöne ist ja, dass das API Gateway vor der Firewall steht. Das heißt, jetzt gehe ich mit diesem Token los und sage, hallo liebes API Gateway, gib mir doch mal bitte alle Informationen, die du so hast. Und das Schöne ist ja, dass das API Gateway sich auf das Backend for Frontend verlässt, wenn es um Autorisierungschecks geht. Das heißt, das sagt einfach, ja, das Backend for Frontend passt schon. Das heißt, ich kann jetzt alles machen, was das Backend for Frontend machen kann für alle User. Und ich kann auch noch Sachen machen, wie das Backend for Frontend nicht machen kann, weil es nicht implementiert ist, die aber das API Gateway unterstützt. Das heißt, ich habe jetzt mehr oder weniger vollen Zugriff auf das API Gateway, könnte damit versuchen, Zahlungen auszulösen, irgendwelche Kulanz Regelungen für meine eigenen Bestellungen einzustellen und all solche schönen Dinge. In der Praxis war das jetzt so, dass beim Kunden natürlich schon noch mal jemand drauf guckt, bevor da irgendwie 10.000 Euro überwiesen werden. Also, es ist jetzt nicht so, dass ich da sofort das ganze Geld hätte raustragen können, aber ich glaube, da könnte auch schon eine gewisse Menge an Schaden anrichten. So, wenn ich jetzt gefragt werde, so wie fixen wir das denn jetzt? Der Kunde kommt zu mir und sagt, ja, alles schön und gut, aber wie kriege ich das denn weg? So, dann ist natürlich die Standardantwort, die man erst mal so gibt, so darf es einfach nicht verschlüsseln, ohne das zu authentifizieren. Das geht immer schief, wirklich. Das könnt ihr nicht machen. So, Moximalensbike, der Mensch, der das Signalprotokoll mitentwickelt hat, hat das the cryptographic doom principle genannt. If you have to perform any cryptographic operations before authenticating the ciphertext, it will somehow inevitably lead to doom. Und das trifft hier ganz gut zu. Der zweite Standard-Tipp, den man im Bereich Cryptografie immer gibt, ist, baut sowas einfach nicht selber, sondern benutzt irgendeine existierende Library dafür. So, aber da kann man jetzt auch wieder sagen, das ist eigentlich auch nicht alles, oder? Also, wenn man nochmal so auf diese Architektur zurückguckt, die wir da gerade gesehen haben, das sind auch noch andere Probleme. Zum Beispiel können wir jetzt mal sagen, wenn wir uns so ganz reingesumed sind, dann sagen wir, okay, hier ist irgendwie so die falsche Verwaltung von Verschlüsselungsalgorithmen. Das soll man nicht machen. Jetzt können wir aber so Google Maps mäßig losgehen und den Zoom-Slider mal ein bisschen runterziehen und sagen, hier stehen irgendwie so volle URLs in den übertragenen Daten, inklusive der Domain. Die Domain ist doch eigentlich fest. Warum steht überhaupt noch in der URL drin? Da könnte man doch nur den Teil dahinter übertragen, sondern nur die relevanten Teile. Oder wenn man diese URL schon auf die Art übertragen will, dann müsste man doch zumindest noch ein paar Checks machen und sagen, okay, ich weiß eigentlich, dass dieser Endpoint immer nur die folgende Teile vom API Gateway aufrufen wird. Da kann man Checks einbauen und sagen, okay, was wird denn da gerade abgerufen, will ich das zulassen. Warum darf das Backend for Frontend überhaupt mit dem offenen Internet reden? Also, ja klar eingehend, verstehe ich, aber warum muss das nach draußen reden können? Das hat doch überhaupt keinen Job, das muss doch genau nur mit dem API Gateway reden können. Warum ist das nicht gefirewollt? Warum steht das API Gateway überhaupt nicht hinter der Firewall? Es ist doch eigentlich auch so, dass auch da man erwarten würde, dass eigentlich nur das Backend for Frontend damit reden kann. Warum muss das fürs gesamte Firmennetz zugreifbar sein? Und als Letztes auch wieder so, warum ist da so ein Topen, das so alles berechtigt? Ist da irgendwie unschön? Kann man das nicht besser machen? Und genau, und das Schöne ist jetzt, dass jeder dieser einzelnen Punkte hier, da kann man jetzt wieder andere Probleme, die das auch erzeugt, drunterschreiben. So, jetzt kann man sagen, okay, falsche Verwendung vom Verschlüsselungsalgorithmen, eventuell kann man da noch andere kryptografische Angriffe ausführen. Auf so einen unauthentifizierten CBC mit Malleable Encryption und so, da gibt es zumindest theoretisch Angriffe, wo man schlimmstenfalls den Key raus tragen könnte am Ende. Die Tatsache, dass dort volle URLs übertragen werden, würde auch ermöglichen, dass man eben andere API Endpoints aufrufen kann durch diese Funktionen, die fehlende Einschränkungen der URLs eben auch das Gleiche, server-side-request-forgery, das war das, was wir auch gerade gemacht haben, so nennt man das. Die Tatsache, dass das Backend for Frontend nicht nach draußen gefirewalled ist, heißt eben auch, dass es sehr einfach ist, wenn ich da drauf irgendwie einen Angriff ausführen kann, dann halt raus zu telefonieren, also eine Remote Shell oder sowas in der Richtung daraus zu ziehen oder auch einfach nur Daten zu exfiltrieren. Die Tatsache, dass das API Gateway nicht gefirewalled ist, heißt eben auch, dass das API Gateway so komplett im Firmnetz hängt und jeder, der halt eine Vulnerability in dem Produkt kennt, kann das einfach exploiten. So, eigentlich auch nicht wirklich notwendig. Und die Verwendung eines God Tokens macht vertrauenswürdiges Logging und Auditing in den Backends komplett unmöglich, weil sich die Backends darauf verlassen müssen, dass das Backend for Frontend ihnen korrekt sagt, wer eigentlich gerade eine Aktion gemacht hat, weil können sich nicht aufs Token verlassen. So, genau. Also als Fazit, wenn ihr auf der Seite der Verteidiger spielt, dann ist die Aussage, Verschlüsselung heißt nicht, dass nichts passieren kann. Da muss man trotzdem immer noch, wenn man Sachen verschlüsselt hat, sollt man trotzdem noch weitere Verteidigungsmechanismen drin haben. Also eine tiefe Verteidigung nennt man das, Defense in Depth. Niemand kann so wirklich vorher wissen, was eigentlich in so einem System drin lauert. Und deswegen sollte man eben eine defensive Architektur wählen, wo man eben unbekannte Bedrohungen abmildern kann. Wo man sagt, ich wüsste zwar nicht, wie es irgendjemand hinkriegen sollte, diese Funktion dazu zu bringen, eine URL abzurufen, die ich nicht kenne, aber ich verhinder es trotzdem. Weil schlimmstenfalls Part CPU Cycles ist doch egal. So, kostet ja nichts. Dabei helfen eben auch Bedrohungsanalysen und Thread-Modeling so als Methodik, um mal wie ein Angreifer auf so ein System drauf zu gucken, kann ich nur empfehlen. Wenn ihr jetzt auf der Seite der Angreifer spielt, also natürlich der Whitehead-Hacker, dann kann ich euch sagen, manchmal findet man auch in so verschlüsselten Daten durchaus was Interessantes. Es lohnt sich, das mal anzuschauen. In dem Bericht, den man dann hinterher schreibt für die Firma, lohnt es sich auch mal heraus zu zoomen und zu sagen, ja, genau, es gibt so diese eine spezifische Sicherheitslücke hier, aber eigentlich heißt, dass das da noch an sechs anderen Stellen, was schief gegangen ist, das erzeugt dann ziemlich einen Mehrwert auch noch mal für den Kunden. Und in der Kryptografie Vorlesung aufpassen lohnt sich. Genau, damit. Vielen Dank für eure Aufmerksamkeit so früh am Morgen. Vielen Dank für den sehr interessanten Vortrag. Ich möchte, wenn es gibt, fragen, Hand hoch. Ja, vielen Dank für den Talk. Mich würde noch interessieren, du hast gemeint, man soll auf jeden Fall dann irgendwie, man soll keine Verschüsselung machen, ohne Authentifizierung. Kannst du noch zwei Worte mehr dazu sagen, wie man das machen würde dann mit Authentifizierung? Ja, also es gibt da verschiedene Möglichkeiten. Zum einen kann man eben zusätzlich zu der normalen Verschlüsselung dann danach noch einen sogenannten Message Authentication Code berechnen, den man auch mitschickt. Das ist dann wieder ein eigener Algorithmus, der dafür da ist, eben nur Daten zu authentifizieren, aber sie nicht zu verschlüsseln. Noch einfacher ist es, wenn man einfach nicht AIS im Cypher-Blockchaining-Modus verwendet, sondern zum Beispiel im GCM-Modus, der bringt die Authentifizierung dann gleich noch mit. Da kriegt man sozusagen beides auf einmal und auch auf eine Art, wo weniger schiefgehen kann, denn sozusagen bei diesen Verschlüsseln und Authentifizieren, wenn man das in der falschen Reihenfolge macht, dann kann es einem auch wieder auf die Füße fallen. Deswegen wäre der tatsächliche praktische Tipp einfach AIS im GCM-Modus verwenden und dann hast du das Problem nicht. Auch von mir einmal Danke für den Talk. Du hast vorhin gesagt, dass API Gateway wäre erst um ganzen Firmenetz erreichbar. Habe ich was falsch verstanden oder saßt du im Firmenetz? Genau, also es war ein bezahlter Pen-Test von der Firma. Das heißt, wir hatten einen VPN-Zugriff dafür, weil die Anwendung selbst auch nur aus dem Firmenetz erreichbar war. Und deswegen mussten wir so oder so im Firmenetz sein. Also ja, sozusagen, ihr jetzt als Externe von der Firma wird nicht in der Lage gewesen, daran zu gehen. Aber alle, die die Anwendung tatsächlich verwenden können, kaum eben auch ans API Gateway. Woher genau kannten wir den Initialisierungsvektor? Der Initialisierungsvektor, der wird, ich gehe nochmal kurz zurück hier, der wird an dieser Stelle hier mit in den Output gegeben. Das heißt, wir kriegen also nicht nur die verschlüsselten Daten, sondern wir kriegen auch den Initialisierungsvektor mitgeliefert vom Server, weil ohne den kann der Server auch nicht mehr entschlüsseln. Und der hat keinen Lust, sich den selber zu merken, das ist relativ normal. Den gibt man dann einfach mit als Teil, also die ersten 16 Byte vom Form Cypher Text davor sind dann in der Regel der Initialisierungsvektor. Ist dieses Cypher-Block chaining überhaupt sicher? Oder sollte man das am besten gar nicht verwenden? Ja, ist X überhaupt sicher? Ist immer so eine Frage, wo man dann wieder fragen muss, vor was denn? Also es gibt Anwendungsfälle, in denen Cypher-Block chaining sicher ist. Zum Beispiel, wenn du es eben mit einer gut implementierten Message Authentication Code-Lösung verwenden ist zusammen. Oder auch vielleicht in Fällen, wo du sagst, ich will die Daten eigentlich nur verschlüsseln, aber mir ist eigentlich sogar egal, ob die Integritätsgesichert sind. Würste jetzt, ehrlich gesagt, gerade spontan keinen Anwendungsfall, in dem das so wäre. Aber es gibt ja durchaus manchmal eine Situation, wo du sagst, eigentlich ist man hauptsächlich sicher, dass es verschlüsselt ist. Aber ja, also in der Regel willst du es mit Authentication verbinden oder halt Gcm verwenden. Gcm ist halt irgendwie, ich weiß nicht, 10, 15 Jahre jünger als CBC. Deswegen sieht man noch recht viel CBC da draußen. Okay. Mir ist noch aufgefallen bei diesem Architekturbild, der Backend for Frontend, der redet mit einem festen Key, dieser gelbe Schlüssel mit dem AP Gateway. Ist das nicht auch schon, kann man das nicht auch schon besser machen oder ist das nicht auch schon schlecht? Also ich habe es hier etwas verkürzt dargestellt. Der hat schon einen dynamischen Key zu einem gewissen Grad, da hängt irgendwo noch so ein Identitätsmanagement System rum, dass halt diesen Backend for Frontend ein eben periodisch alle fünf Minuten oder so ein neues Token ausstellen kann, wo sich das Backend for Frontend das abholt. Insofern ist es also nicht ganz statisch, wenn ich das Ding einmal klaue, dann habe ich halt Zugriff für die restliche Gültigkeit dieses Tokens. Aber das ist natürlich was, was sich sehr gut automatisieren lässt, so ein Angriff, dementsprechend ist es in der Praxis kein wirklicher Sicherheitsgewinnen dann für das System. Aber ja, genau. Also prinzipiell ist der Schaden erst mal begrenzt, wenn es wegkommt, weil es halt nach einer gewissen Zeit abläuft von alleine. Okay, wenn keine weiteren Fragen, herzlichen Dank. Und in fünf Minuten.