Verschlüsselung: Welcher Blockmode, welches Padding?

mccae

Senfdazugeber
Hallo,

Ich habe da generell eine Frage was Verschlüsselung in Java angeht.
Bis jetzt habe ich jegliche Cipher nur unter Angabe des Algorithmus und des zuvor generierten Keys initialisiert.

Ich möchte nämlich Daten verschlüsselt auf die Platte schreiben.
Am bequemsten geht es für mich mit Sealed Objects welche ich so erstelle:

Java:
		Cipher cipher = Cipher.getInstance("AES");
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		
		SealedObject so = new SealedObject(data, cipher);

Nun habe ich etwas über die Verschlüsselungsalgorithmen gelernt und bin auf "Blockmodes" und "Paddingalgorithms" gestoßen.

Ich wurde darauf hingewiesen, ich solle beides je nach Verwendungszweck des Ciphers angeben.

Muss ich das?

Soweit ich weiß, füllt der Paddingalgorithmus bei Blockciphern die fehlenden Bytes damit die Anzahl der Blöcke zum Beispiel bei AES durch eine bestimmte Zahl teilbar sind.

Was den Blockmode (zusammen mit "Initialization-vectors" usw.) angeht, bin ich überfordert.
Im Internet steht was die Modi jeweils machen, doch deren Verwendungszweck ist mir unbekannt.

Vorgeschlagen wurde mir: "AES/ECB/PKCS5Padding".

Was soll ich in diesem Fall nehmen?
Ich weiß nicht welches Padding und welcher Blockmode für welche Situation am besten sind.

Welche Default-Blockmodes und Paddingalgorithmen werden bei Initialisierung eines Ciphers mit "AES" benutzt (Beim standard Cryptographic Provider)?

Und: Bei einer Verschlüsselung eines I/O Streams - welche Modi/Paddings wären da zu wählen?

Denn es geht in beiden Fällen immer um Daten mit undefinierter Größe welche verschlüsselt werden müssen.

Könnt ihr mir helfen?

lg,
Martin
 
Zuletzt bearbeitet:
Hi,

der Blockmode ist meiner Meinung nach recht schön auf Wikipedia beschrieben, die entsprechenden Englischkenntnisse vorrausgesetzt.

Zum Padding:
AES arbeitet ja mit Blöcken der Größe 128 Bit. ( = 16 Byte). Liegen jetzt allerdings (zum Beispiel) nur 10 Byte an Daten vor, dann müsstest du eigentlich warten, bis du 16 Bytes zusammen hast. Da dies natürlich lange dauern kann, gibt es jetzt verschiedene Standards, wie du den Block "auffüllen" kannst, so dass du ihn verschlüsseln kannst.
Infos über die verschiedenen findest du wieder auf Wikipedia.

Was standardmäßig bei Java verwendet wird kann ich dir jetzt leider nicht beantworten, eventuell hilft hier ein Blick in die Java Dokumentation. Aber ich tipp mal auf ECB ohne Padding.

Gruß,
BK
 
Hallo,

Danke für die Antworten.
Also werde ich die Sache mit ECB streichen und einen anderen Blockmode nehmen.

Will ich nun CBC benutzen, dann wird, sofern nichts angegeben wurde, ein zufälliger Initialisationsvektor erstellt.
Um die Nachricht wieder zu entschlüsseln, nehme ich an dass ich diesen wieder benötige.

In Ordnung - doch gibt es dafür Beispiele?
Ich weiß, dass ich dem Cipher den IV mit getIV den Vektor entnehmen kann, aber wie führe ich einem Cipher auf der "anderen Seite" diesen wieder zu?

Und nun zum Padding.
Ok, fehlende Bytes in Blöcken müssen aufgefüllt werden damit diese komplett sind.
Ich habe bis jetzt bei Blowfish und anderen nichts angegeben und es hat immer alles funktioniert.

Laut den Java Docs geschieht folgendes, was dies erklärt:
For example, the SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers.

Dort steht jedoch nichts über standard Blockmodes und Paddingalgorithmen in Verbindung mit AES oder anderen Algorithmen.

In dem verlinkten Wikipediartikel über Padding steht, dass PKCS5-Padding technisch nur für Blockgrößen von 64-bit (wie Blowfish,...) geeignet ist, was eigentlich für PKCS7-Padding spricht.

Denn die Blockgröße für AES ist 128-bit.
Nur unterstützt Java angeblich kein Padding nach PKCS-7.
Oder funktioniert die Sache trotzdem mit Padding nach PKCS-5?

Gibt es so etwas wie eine JVM-Abhängige Liste von unterstützten Algorithmen in Verbindung mit Blockmodes und Paddings unter Verwendung von Sun's JCE?

Der Bouncycastle Provider wäre jetzt nämlich der Overkill.


Und nebenbei: Wie sieht's denn im Jahr 2012 mit Keygrößen aus?
Fallen Keys mit einer Länge >128bit immer noch unter merkwürdige amerikanische Exportgesetze?
Denn das Limit bei meinem JDK scheint immer noch 128bit für AES zu sein.

Gilt diese Beschränkung auch für JREs?
Ein Installieren von extra Policies kann ich niemandem zumuten.

Grüße,
Martin
 
Hallo,

Nochmals danke für deinen Post.
Jetzt ist soweit alles klar.

Nur eine kleine Nebenfrage:
Wenn ich jetzt Cipher I/O Streams verwenden will (anstatt SSL Sockets und Rumpfuschen an Zertifikaten/Certificatestores):
Muss vor dem Arbeiten mit dem Stream auf der anderen Seite je nach Blockmodus der IV bekannt sein?

Gibt es eine Möglichkeit dies automatisiert ablaufen zu lassen, ohne dass ich mich um die darunterliegende Verschlüsselung kümmern muss?
Denn ich möchte nicht das Rad neu erfinden.

mfg,
 
Hi,

bisschen OT:
was spricht gegen einen SSL-Socket mit entsprechenden Zertifikaten? Dies wäre eine ganze Ecke höher von der Abstrahierung, da müsstest du dich gar nicht mehr um die Verschlüsselung und Entschlüsselung an sich kümmern. Dadurch ist auch nicht so leicht, durch einen Leichtsinnsfehler in der Implementierung die ganze Verschlüsselung überflüssig / nutzlos zu machen.

Gut, den Zertifikatstore finde ich persönlich auch nen Pfusch, konnte mich mit dem bisher nicht anfreunden. Mir wäre es lieber man könnte die Zertifikate einfach als .pem angeben und fertig. Aber einmal ein Cert erstellt und den öffentlichen Teil darin gespeichert und schon läuft der Server.

Zusöätzlich wäre es dann noch weniger Code, der von dir geschrieben werden müsste und somit weniger Wartungsaufwand.

Zurück zum Thema:
Muss vor dem Arbeiten mit dem Stream auf der anderen Seite je nach Blockmodus der IV bekannt sein?
Ganz sicher kann ich es dir nicht sagen, aber soweit ich das noch richtig im Kopf und verstanden habe brauchen beide Seiten den IV. Der Rundenschlüssel wird ja mit Hilfe des IV jede Runde neu berechnet, also ist dieser essentiell.

Gibt es eine Möglichkeit dies automatisiert ablaufen zu lassen, ohne dass ich mich um die darunterliegende Verschlüsselung kümmern muss?
Nicht dass ich wüsste.

Gruß,
BK
 
Zuletzt bearbeitet:
Hallo,

Yay, mein 200ster Beitrag!

Also, ein SSLSocket wäre natürlich eine tolle Lösung, nur gefällt mir die Sache mit den CertificateStore und Truststore nicht.

Ich brauche eine Lösung, die "out of the box" funktioniert.

Gibt es da überhaupt keine einfache API, welche gleiche oder ähnliche Funktionalitäten wie SSLSockets und dergleichen anbietet?

Denn das Herumpfuschen an irgendwelchen Keystores kommt nicht in Frage.

mfg,
 
Zurück