Langsam AES-GCM-Verschlüsselung und-Entschlüsselung mit Java 8u20

Ich versuche zu ver-und entschlüsseln von Daten unter Verwendung von AES/GCM/NoPadding. Ich installierte JCE Unlimited Strength Policy Files und ran an die (simple minded) benchmark unten. Ich habe das gleiche getan mit OpenSSL und war in der Lage, mehr zu erreichen, als 1 GB/s - Verschlüsselung und-Entschlüsselung auf meinem PC.

Mit der benchmark unten ich bin nur in der Lage, 3 MB/s - Verschlüsselung und-Entschlüsselung mit Hilfe von Java 8 auf dem gleichen PC. Keine Ahnung, was ich falsch mache?

public static void main(String[] args) throws Exception {
    final byte[] data = new byte[64 * 1024];
    final byte[] encrypted = new byte[64 * 1024];
    final byte[] key = new byte[32];
    final byte[] iv = new byte[12];
    final Random random = new Random(1);
    random.nextBytes(data);
    random.nextBytes(key);
    random.nextBytes(iv);

    System.out.println("Benchmarking AES-256 GCM encryption for 10 seconds");
    long javaEncryptInputBytes = 0;
    long javaEncryptStartTime = System.currentTimeMillis();
    final Cipher javaAES256 = Cipher.getInstance("AES/GCM/NoPadding");
    byte[] tag = new byte[16];
    long encryptInitTime = 0L;
    long encryptUpdate1Time = 0L;
    long encryptDoFinalTime = 0L;
    while (System.currentTimeMillis() - javaEncryptStartTime < 10000) {
        random.nextBytes(iv);
        long n1 = System.nanoTime();
        javaAES256.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(16 * Byte.SIZE, iv));
        long n2 = System.nanoTime();
        javaAES256.update(data, 0, data.length, encrypted, 0);
        long n3 = System.nanoTime();
        javaAES256.doFinal(tag, 0);
        long n4 = System.nanoTime();
        javaEncryptInputBytes += data.length;

        encryptInitTime = n2 - n1;
        encryptUpdate1Time = n3 - n2;
        encryptDoFinalTime = n4 - n3;
    }
    long javaEncryptEndTime = System.currentTimeMillis();
    System.out.println("Time init (ns): "     + encryptInitTime);
    System.out.println("Time update (ns): "   + encryptUpdate1Time);
    System.out.println("Time do final (ns): " + encryptDoFinalTime);
    System.out.println("Java calculated at " + (javaEncryptInputBytes / 1024 / 1024 / ((javaEncryptEndTime - javaEncryptStartTime) / 1000)) + " MB/s");

    System.out.println("Benchmarking AES-256 GCM decryption for 10 seconds");
    long javaDecryptInputBytes = 0;
    long javaDecryptStartTime = System.currentTimeMillis();
    final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * Byte.SIZE, iv);
    final SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
    long decryptInitTime = 0L;
    long decryptUpdate1Time = 0L;
    long decryptUpdate2Time = 0L;
    long decryptDoFinalTime = 0L;
    while (System.currentTimeMillis() - javaDecryptStartTime < 10000) {
        long n1 = System.nanoTime();
        javaAES256.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
        long n2 = System.nanoTime();
        int offset = javaAES256.update(encrypted, 0, encrypted.length, data, 0);
        long n3 = System.nanoTime();
        javaAES256.update(tag, 0, tag.length, data, offset);
        long n4 = System.nanoTime();
        javaAES256.doFinal(data, offset);
        long n5 = System.nanoTime();
        javaDecryptInputBytes += data.length;

        decryptInitTime += n2 - n1;
        decryptUpdate1Time += n3 - n2;
        decryptUpdate2Time += n4 - n3;
        decryptDoFinalTime += n5 - n4;
    }
    long javaDecryptEndTime = System.currentTimeMillis();
    System.out.println("Time init (ns): " + decryptInitTime);
    System.out.println("Time update 1 (ns): " + decryptUpdate1Time);
    System.out.println("Time update 2 (ns): " + decryptUpdate2Time);
    System.out.println("Time do final (ns): " + decryptDoFinalTime);
    System.out.println("Total bytes processed: " + javaDecryptInputBytes);
    System.out.println("Java calculated at " + (javaDecryptInputBytes / 1024 / 1024 / ((javaDecryptEndTime - javaDecryptStartTime) / 1000)) + " MB/s");
}

EDIT:
Ich lass es als nette übung um das zu verbessern einfach gemerkt benchmark.

Ich getestet habe, etwas mehr über die ServerVM, entfernt nanoTime Anrufe und eingeführt, warm-up, aber wie ich es erwartet keiner von diesen hatte jede Verbesserung auf die benchmark-Ergebnisse. Es ist flach-gefüttert in 3 Megabyte pro Sekunde.

  • Erstens, der Vergleich ist falsch: kein warmup, iteration, übermäßige nanoTime Anrufe. Hotspot ist die systeminterne Funktionen für AES-NI sind nur mit einem optimierenden JIT-compiler, die Sie haben, um es zu erreichen, bevor die Beurteilung der Leistung. Zweitens versuchen, AES/CBC. Tun Sie tatsächlich zu Messen, aes-gcm mit OpenSSL, und es gab Sie 1 GB/s?
  • Beachten Sie auch, dass zur Verwendung der AES-NI-Interna, es ist erforderlich für die Verwendung der Server-VM, eine moderne Intel-CPU mit Unterstützung, und haben ein warm-up Sequenz. Beachten Sie, dass OpenSSL ist eine der am schnellsten libs gibt, byte-code kann relativ schnell für die business-Logik, aber für Kryptografie sehen Sie Unterschiede mit gut umgesetzten C/C++ - Bibliotheken.
  • Ja, ich weiß, das ist nicht der robusteste benchmark, aber 3 MB/s vs. 1 Gbit/s ist immer noch sehr wichtig und ich fühle mich auf diese einfältige benchmark ist gut genug, um den Punkt über. Ich habe versucht, AES/CBC, und ich bin in der Lage, mehr als 400 MB/s für die Verschlüsselung und mehr als 1 GB/s für die Entschlüsselung, die mit Java ' s cipher.
  • Ich Schreibe meine eigenen JavaFX - /Java-EE-Anwendung testen, mit einem tollen GUI, gehen Sie durch den gesamten Prozess der Authentifizierung eines Benutzers mithilfe von SRP und dann das senden von verschlüsselten Dateien über WebSocket mit AES/GCM. Ich zurück, mit einem link, wenn die app fertig ist. Aber für jetzt, alles, was ich sagen wollte ist, dass im Vergleich mit unverschlüsselten Datei übertragen, unter Verwendung von AES/GCM ist etwa 10-mal langsamer für mich (96-bit-Authentifizierungs-Tags, 128-bit-Schlüssel & IV).
  • Sie haben nicht die Unlimited Strength Jurisdiction Policy-Dateien installiert.
InformationsquelleAutor Christo | 2014-09-23
Schreibe einen Kommentar