2017-01-26 3 views
0

Was ist der einfachste Weg in Java, Null-Padding am Ende einer Zeichenfolge hinzuzufügen? Dies ist ein Vorschritt in einem Verschlüsselungsprozess, daher muss die resultierende Zeichenfolge ein Vielfaches von 16 Byte sein.Java: Pad einen String mit ASCII 0 (NULL) auf ein Vielfaches von 16 Bytes

Der erste Versuch bestand nur darin, String 1 mit einer Zeichenfolge zu füllen, die null enthält. Aber das funktioniert nicht, weil null zum Wort 'null' wird.

Zweiter Versuch: Konvertieren Sie die Zeichenfolge in Bytes, und fügen Sie irgendwie Null Bytes an, aber ich war nicht in der Lage, eine Möglichkeit zu finden, das zu arbeiten.

Dritter Versuch: Initialisieren Sie ein Byte-Array einer bekannten großen Größe wie 128 minus die Länge der Bytes in meiner Zeichenfolge, dann konvertieren Sie meine Zeichenfolge in Bytes kopieren Sie die beiden Arrays zusammen. So etwas wie:

String stringToEncrypt = "some data" ; 
byte[] stringToEncryptBytes = stringToEncrypt.getBytes("UTF-8"); 
int stringToEncryptByteLength = stringToEncryptBytes.length; 

int sizeOfNullArray = 128 - stringToEncryptByteLength; 
byte[] byteBlockOfNulls = new byte[sizeOfNullArray] ; 

byte[] finalBytes = new byte[stringToEncryptByteLength + sizeOfNullArray]; 
System.arraycopy(stringToEncryptBytes, 0, finalBytes, 0, stringToEncryptByteLength); 
System.arraycopy(byteBlockOfNulls, 0, finalBytes, stringToEncryptByteLength, sizeOfNullArray); 

Aber wenn ich das Byte-Array wieder in eine Zeichenfolge konvertieren, wird es nur verstümmelt. Also muss ich etwas falsch gemacht haben.

+0

Hmm, ich verwendet toString() vor dem hat nicht funktioniert. Jetzt, da ich die Bytes wieder korrekt in einen String umgewandelt habe, indem ich den String finalString = new String (finalBytes, "UTF-8") verwende, kann ich die richtige Zeichenfolge sehen. Ich bin jedoch immer noch neugierig, ob mein dritter Versuch der beste/einfachste Weg ist, einen String mit Nullen auf eine bestimmte Größe zu puffern. –

Antwort

0

Wenn Sie sagen, „das ist ein Pre-Schritt in einem Verschlüsselungsprozess ist“, reden Sie padding den Klartext eine Blockgrenze zu verschlüsseln, zu erreichen, oder Schlüssel Stretching einen Schlüssel von der richtigen Länge zu bilden ? "Null Padding" ist in beiden nicht ideal, aber es ist geradezu gefährlich in der Schlüsselableitung.

Wenn Ihre Frage ersteres ist, möchten Sie wahrscheinlich PKCS7Padding (auch PKCS5Padding in Java genannt) verwenden, die works in the following manner:

  • Wenn die Nachrichtenlänge ist weniger als eine volle Blockgrenze (dh lengthBytes % 16 != 0), Der letzte Block wird mit N Bytes aufgefüllt, wobei N = 16 - (lengthBytes % 16) ist, und der Wert jedes Bytes ist N. Beispiel: Wenn der letzte Block 13 Byte ist, wird er mit 0x03 0x03 0x03 aufgefüllt, um eine Länge von 16 zu erreichen.
  • Wenn die Nachrichtenlänge ein genaues Vielfaches der Blockgröße ist (dh lengthBytes % 16 == 0), wird ein vollständiger Block (16 Byte) von 0x10 wird hinzugefügt.

Der Link oben erklärt die vollständige Begründung dafür. Zero-Padding-/Null-Padding-Schemata werden aus verschiedenen Gründen nicht empfohlen.

Wenn dies ist eigentlich eine Frage, wie der Code für eine Übung zu implementieren, wird die folgende Methode funktioniert (auf einem einzigen Block arbeitet, keine vollständige Klartext):

String plaintext = "This is text"; // 12 bytes 
byte[] plainBytes = plaintext.getBytes(StandardCharsets.UTF_8); 
byte[] paddedBytes = new byte[16]; 
System.arraycopy(plainBytes, 0, paddedBytes, 0, plainBytes.length); 

assert paddedBytes.length == 16; 
assert paddedBytes[12] == (byte) 0x00; 
assert paddedBytes[13] == (byte) 0x00; 
assert paddedBytes[14] == (byte) 0x00; 
assert paddedBytes[15] == (byte) 0x00; 

Das resultierende Byte-Array, wenn zurück in eine Zeichenfolge konvertiert, wird aussehen.

This is text | <-- There will be four "unprintable character" indicators because 0x00 is not a printable character in UTF-8 
+0

Den Klartextblock auf ein Vielfaches von 16 auffüllen, wenn der Klartextblock selbst in der Größe zwischen etwa 33 Bytes und etwa 100 Bytes variieren kann. Dies ist Teil einer Schnittstelle mit einem Anbieter, also sind meine Hände gebunden.Ich kann PKCS5 oder 7 nicht verwenden, weil der Hersteller ausdrücklich möchte, dass ASCII 0 (null) das Padding am Ende der Zeichenfolge ist. –

+0

Ok, in diesem Fall einfach das 'Byte [L]' zuweisen, wobei * L * die gewünschte Nachrichtenlänge und ein Vielfaches von 16 ist und dann 'System.arraycopy()' wie oben beschrieben funktioniert. Um klar zu sein - der * Block * ist kein "Vielfaches von 16" (naja, es ist genau "1 * 16"); jeder Block * ist * 16 Bytes und die gepolsterte * Nachricht * sollte ein Vielfaches (> = 1) von 16 sein. – Andy

+0

Danke für die Info. Später im Code mache ich das: Cipher cipher = Cipher.getInstance ("AES/CBC/NoPadding"); . Ich nehme an, dass das die Chiffre-Instanz ist, die ich will, da ich das Padding manuell behandle. Ich werde bald mit dem Verkäufer sprechen und sehen, ob sie die Standard-PKCS-Sachen verwenden können. –

Verwandte Themen