In Java war die alte Art, einen geheimen Schlüssel wie ein Passwort zu speichern, char[]
, da Sie seine Daten überschreiben konnten, wenn Sie damit fertig waren. Dies hat sich jedoch seither als unsicher erwiesen, da der Garbage Collector beim Umorganisieren des Heap die Dinge kopieren wird. Auf bestimmten Architekturen ist es möglich, dass eine Seite freigegeben wird, und das Geheimnis bleibt bestehen, wenn ein anderes Programm dieselbe Seite zuweist.Ist es möglich, in Java Geheimnisse auf dem Stack zu speichern?
Das ist schrecklich hässlich, aber was ist, wenn das Geheimnis auf dem Stapel von run
eines Threads gespeichert wurde? Es wäre noch Vorsicht geboten, den Thread elegant zu beenden, so dass er seine Daten auf Null setzen könnte, aber dieses Problem war auch in der alten Form vorhanden.
Ein großes Problem, das ich sofort feststellen kann, ist, dass ich mir keinen sicheren Weg vorstellen kann, um Daten in den Container zu bekommen. Sie können die Wahrscheinlichkeit eines ausgelaufenen Geheimnisses minimieren, indem Sie Streams mit sehr kleinen internen Puffern verwenden, aber am Ende werden Sie mit dem gleichen Problem wie char[]
enden. [Edit: Würde ein einzelnes Mitglied private static byte
und eine Flagge funktionieren? Dies würde Sie jedoch auf ein Geheimnis pro ClassLoader beschränken. Dies fügt mehr Hässlichkeit hinzu, aber es könnte leicht genug sein, sich hinter einer gut geschriebenen Schnittstelle zu verstecken.]
Also ich habe eine Menge Fragen, wirklich.
Ist der Stapel von diesen Angriffstypen sicherer als der Heap? Gibt es reine Java-Mechanismen, um eine Stapel-zu-Stapel-Kopie zwischen zwei verschiedenen Stapelrahmen auf eine Weise durchzuführen, die für dieses Problem nützlich wäre? Wenn nicht, würde die JVM diese Art von Operation sogar in Bytecode unterstützen?
[Edit: Bevor die Menschen zu viel Sorge, dies ist eher ein Gedankenexperiment als alles andere. Ich habe absolut nicht die Absicht, "in der Produktion zu testen" oder es in einem aktuellen Projekt zu verwenden. Mir ist klar, dass das, worüber ich rede, wirklich hässlich ist, wahrscheinlich schrecklich sperrig, und wirkt gegen die gesamte JVM-Struktur. Ich bin nur daran interessiert, ob es möglich ist, ob es meine Ziele tatsächlich erreicht, und welche Arten von heroics es dauern würde, um sie geschehen.]
Wenn Sie über einen Angreifer zu Recht besorgt sind, um Daten wie diese bekommen Zugang, die Chancen sind Sie sowieso geschraubt sind, weil jeder Angreifer ausgefeilt genug besorgt zu sein auf diesem Niveau anspruchsvoll genug ist, fast alles brechen Sie können Wirf sie an. –
Im Prinzip stimme ich zu, aber das ist ein sehr schlechtes Argument, um eine Bedrohung zu schließen. Wie auch immer, ich habe diesen Weg eingeschlagen, als ich eine Liste von Sicherheitsanforderungen durchgesehen habe, die mir mein Kunde zur Verfügung gestellt hat. Einer besteht darin, dass wir Geheimnisse immer im Speicher auf Null setzen. Wenn dies nicht geschieht, wird der Kunde sie überprüfen. Der Klient ist schlau genug zu verstehen, dass 'char []' nicht funktionieren wird, aber sie verlangen auch, dass wir Java benutzen. Zum Glück sind sie vernünftige Leute, sie erkennen den Konflikt und es ist nicht zu groß. Aber es hat mich dazu gebracht zu denken ... –
sehr schlechtes Argument gegen das Schließen einer Bedrohung * - Entschuldigung, Bearbeitungszeitraum abgelaufen. –