nicht entschlüsseln, was ich verschlüsselt habe

Ich habe ein komisches Problem ...

Basiert meine Lösung aufEntschlüsseln einer fest codierten Datei als Byte []

Also habe ich eine kleine Cypher-Klasse geschrieben, um beim Verschlüsseln / Entschlüsseln zu helfen ... Früher hat sie einen Schlüssel nachgebildet, der an einem bestimmten Ort fest codiert ist, und einen anderen vorverschlüsselten Schlüssel, der an einem anderen Ort gespeichert ist. Aber das ist etwas irrelevant atm.

Der Verschlüsselungsprozess lief wie folgt ab:

Rufen Sie das fest codierte Byte-Array abVerwenden Sie es, um key2 zu entschlüsselnVerwenden Sie key2, um Daten zu entschlüsselnVerwenden Sie key1, um die Daten weiter zu entschlüsselnDaten entschlüsselt haben

Ich habe die verschlüsselten Daten als Hex-Zeichenfolge gespeichert und diese beiden Funktionen verwendet, um dort hinein- und herauszukommen

private static String byteArrayToHexString(byte[] b)
{
    StringBuffer sb = new StringBuffer(b.length * 2);
    for (int i = 0; i < b.length; i++)
    {
        int v = b[i] & 0xff;
        if (v < 16)
        {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
}

private static byte[] hexStringToByteArray(String s)
{
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++)
    {
        int index = i * 2;
        int v = Integer.parseInt(s.substring(index, index + 2), 16); //THIS LINE
        b[i] = (byte) v;
    }
    return b;
}

Das hat einwandfrei funktioniert; Tatsächlich hat es so gut funktioniert, dass ich es in mein reales Projekt implementiert habe. Das Projekt konnte nicht ausgeführt werden, da ich es nicht gründlich getestet habe.

Es hat sich herausgestellt, dass fast alle Dateien mit einer Ausnahme OK verschlüsselt / entschlüsselt werden - diese will man nicht entschlüsseln.

Ich habe das Problem jedoch festgestellt - DIESE Zeile löst eine IllegalNumberFormat-Ausnahme aus. Irgendwann habe ich das kennengelernthttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 auch. Ich würde und kann auf diese Methode zurückgreifen, wenn jemand eine Möglichkeit beschreibt, einen Fall zu umgehen, bei dem eine Zeichenfolge der Länge 2 in vier Bytes konvertiert wird, die eine IllegalNumberFormatException auslösen.

Da ich eine Datei nicht entschlüsseln kann (und sie hier natürlich nicht zum Ausprobieren freigeben kann), musste ich sie irgendwie umwandeln, um sie transportsicher zu machen. Geben Sie die Base64Coder-Klasse ein, die Base64-Zeichenfolgen codiert ...

Das schien ein neues Problem mit sich gebracht zu haben - die Polsterung wurde aufgebraucht.

Die Frage ist einfach - was mache ich falsch? Ich muss mich an diese Daten anpassen und sie müssen in der Lage sein, richtig und gleichermaßen zu verschlüsseln / entschlüsseln. Ich hätte gerne einen Vorschlag für eine möglichst leichte Lösung mit möglichst wenig Kopieren / Einfügen ... Pseudocode reicht hier nicht aus.

Folgendes mache ich jetzt ...

public static char[] encrypt2(byte[] value) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(true);
    System.err.println("encrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters());
    byte[] encrypted = cipher.doFinal(value);

    SecretKeySpec key2 = getSecretKeySpec(false);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key2, cipher.getParameters());
    byte[] encrypted2 = cipher.doFinal(encrypted);

    return Base64Coder.encode(encrypted2);
}

public static byte[] decrypt2(char[] message) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(false);
    System.err.println("decrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key1);
    byte[] decrypted = cipher.doFinal(Base64Coder.decode(message));

    SecretKeySpec key2 = getSecretKeySpec(true);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key2);
    byte[] decrypted2 = cipher.doFinal(decrypted);

    return decrypted2;
}

Beachten Sie, dass die Schlüssel derzeit zu Testzwecken vollständig verfügbar (fest codiert) sind.

Hier ist mein Testfall

public static void main(String... args) throws Exception
{
    //      byte[] data = "hello".getBytes();
    File PEM = new File(PATH_TO_FILES + SOURCE_PEM);
    File DER = new File(PATH_TO_FILES + SOURCE_DER);
    File cryptoPEM = new File(PATH_TO_FILES + "cryptopem");
    File cryptoDER = new File(PATH_TO_FILES + "cryptoder");

    byte[] cryptokey = encryptA(ASSET_KEY);
    System.out.println(new String(cryptokey));

    //pem key
    System.out.println("PEM");
    byte[] data = getBytesFromFile(PEM);
    char[] crypted = encrypt2(data);
    //      FileOutputStream fos = new FileOutputStream(cryptoPEM);
    FileWriter fw = new FileWriter(cryptoPEM);
    fw.write(crypted);
    fw.flush();

    //der key
    System.out.println("DER");
    data = getBytesFromFile(DER);
    crypted = encrypt2(data);
    fw = new FileWriter(cryptoDER);
    fw.write(crypted);
    fw.flush();

    //opentext
    System.out.println("checking PEM...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoPEM));
    byte[] decrypted = decrypt2(crypted,  false);
    byte[] decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(PEM), decryptedData)) { throw new Exception("PEM Data was not decrypted successfully"); }

    System.out.println("checking DER...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoDER));
    decrypted = decrypt2(crypted,  false);
    decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(DER), decryptedData)) { throw new Exception("DER Data was not decrypted successfully"); }
}

Und ich erhalte jetzt eine InvalidBlockSizeException ... Bitte, jemand beleuchtet das, ich möchte nur, dass es funktioniert ...

Das Ersetzen von "key2" für eine IV, die später in einem "AES / CBC / PKCS5Padding" verwendet wird, ist eine Option, die ich derzeit in Betracht ziehe. Im Wesentlichen ändert sich nichts außer dem zweiten Schritt der Verschlüsselung. Theoretisch und metodisch würde ich die Dinge gleich halten - es sei denn natürlich, es wird eine bessere Lösung beschrieben.

Abschließend möchte ich darauf hinweisen, dass dies eine Programmiererfrage und keine Frage für IT-Sicherheitsstudenten ist. Daher wird richtiger Code mehr geschätzt als eine theoretische Antwort, die unwahrscheinliche Randfälle abdeckt.

EDIT: Nun, ich kann Ihnen die Zahlen, die die IllegalNumberFormatException verursachen, nicht geben, weil ich den Code von heute Morgen verloren habe. Ich kann das Problem scheinbar nicht replizieren, also denke ich, dass der Versuch, diesen Teil zu finden, keinen Nutzen hat.

Hier ist die Ausgabe des Beispieltests:

encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
5@��_׵G�j��!�c;D�i�lR?z�j\
PEM
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
DER
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
checking PEM...
decrypt():  javax.crypto.spec.SecretKeySpec@15c78
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

was bedeutet, dass Base64 es irgendwie vermasselt ...

Antworten auf die Frage(3)

Ihre Antwort auf die Frage