2013-08-26 9 views
5

Ich benötige AES256 Verschlüsselung/Entschlüsselung in einer kommerziellen Webanwendung. Gegenwärtig ist alles mit einer Schlüsselgröße von 128 gut. Das ist kryptographisch nicht befriedigend, also ist mein Problem, wie man dieses Problem am besten umgehen kann, ohne dass der Benutzer irgendetwas manuell installieren muss.Java: Patchen der clientseitigen Sicherheitsrichtlinie aus Applet für AES256

Ich habe die JAR-Dateien mit unbegrenzter Zuständigkeit von Oracle, aber ich habe keine Ahnung, ob das Ersetzen dieser im JRE/lib/security-Verzeichnis des Benutzers mit älteren Versionen kompatibel ist. Offensichtlich möchte ich die JRE des Benutzers nicht beschädigen. Ich habe auch eine Schreibberechtigung für mein JRE-Sicherheitsverzeichnis, aber ich nehme an, dass einige Benutzer diese Rechte nicht haben.

Gibt es einen einfachen Weg um dieses Problem, oder bin ich entweder mit schwachen Verschlüsselung oder einem potenziell problematischen Schritt für Benutzer fest?


Update für "unrestricting" javax.crypto.JceSecurity

@ntoskml Sie richtig sind. getMaxAllowedKeyLength gibt immer noch die begrenzte Schlüsselgröße zurück, aber die Verschlüsselung ist erfolgreich mit der Schlüsselgröße == 256 :). Ich werde meine Testmethode aktualisieren und die Schlüsselgröße festlegen, wenn eine starke Verschlüsselung verfügbar ist. Dank

>>> from javax.crypto import Cipher 
>>> Cipher.getMaxAllowedKeyLength("AES") 
128 
>>> from java.lang import Class 
>>> c = Class.forName("javax.crypto.JceSecurity") 
>>> isRestricted = c.getDeclaredField("isRestricted") 
>>> isRestricted.setAccessible(True) 
>>> isRestricted.set(None, False) 
>>> isRestricted.get(None) 
False 
>>> Cipher.getMaxAllowedKeyLength("AES") 
128 
>>> from javax.crypto import KeyGenerator 
>>> kge = KeyGenerator.getInstance("AES") 
>>> kge.init(256) 
>>> aesKey = kgen.generateKey() 
>>> c2 = Cipher.getInstance("AES") 
>>> c2.init(Cipher.ENCRYPT_MODE, aesKey) 
>>> c2.doFinal("test") 
array('b', [-81, 99, -61, -51, 93, -42, -68, -28, 107, 59, -109, -98, -25, 127, 37, 23]) 

Und der Testfall nach

Jython-Konsole neu starten
>>> # Reflection as above 
>>> isRestricted.get(None) 
True 
>>> kge.init(256) 
>>> aesKey = kge.generateKey() 
>>> c2.init(Cipher.ENCRYPT_MODE, aesKey) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
     at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1011) 
     at javax.crypto.Cipher.implInit(Cipher.java:786) 
     at javax.crypto.Cipher.chooseProvider(Cipher.java:849) 
     at javax.crypto.Cipher.init(Cipher.java:1213) 
     at javax.crypto.Cipher.init(Cipher.java:1153) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 

java.security.InvalidKeyException: java.security.InvalidKeyException: Illegal key size or default parameters 

Bingo :) Vielen Dank für die gemeinsame Nutzung @ntoskml

+0

Bitte die Frage nicht auf diese Weise bearbeiten - zur Zeit es ist ein bisschen schwer für Menschen zu lesen für eine Lösung suchen. Ich möchte auch die Einschränkungen bei der Verwendung dieser Antwort wissen. Normalerweise erlauben es Applets nicht, Reflexionen auf diese Weise zu verwenden - zumindest nicht, wenn sie im Browser ausgeführt werden. –

+0

@owlstead Wo soll ich das hinstellen? – drew

+0

Diese Methode in Applet arbeitet Windows 8 mit 64-Bit-Java (TM) SE Runtime Environment 1.7.0_21 – drew

Antwort

5

EDIT: Hier ist eine aktualisierte Antwort auf diese Frage: How to avoid installing "Unlimited Strength" JCE policy files when deploying an application?


Es ist möglich, die Schlüsselgröße Einschränkungen einfach mit ein paar Zeilen Reflexion zu deaktivieren. Wir verwenden diese Methode in unserem Programm, das für Interoperabilitätszwecke Zugriff auf 256-Bit-Kryptographie benötigt.

private static void removeCryptographyRestrictions() { 
    if (!isRestrictedCryptography()) { 
     return; 
    } 
    try { 
     java.lang.reflect.Field isRestricted; 
     try { 
      final Class<?> c = Class.forName("javax.crypto.JceSecurity"); 
      isRestricted = c.getDeclaredField("isRestricted"); 
     } catch (final ClassNotFoundException e) { 
      try { 
       // Java 6 has obfuscated JCE classes 
       final Class<?> c = Class.forName("javax.crypto.SunJCE_b"); 
       isRestricted = c.getDeclaredField("g"); 
      } catch (final ClassNotFoundException e2) { 
       throw e; 
      } 
     } 
     isRestricted.setAccessible(true); 
     isRestricted.set(null, false); 
    } catch (final Throwable e) { 
     logger.log(Level.WARNING, 
       "Failed to remove cryptography restrictions", e); 
    } 
} 

private static boolean isRestrictedCryptography() { 
    return "Java(TM) SE Runtime Environment" 
      .equals(System.getProperty("java.runtime.name")); 
} 

Allerdings ist unser Programm nicht ein Applet, und ich bin nicht sicher, ob Applets Zugriff auf das Reflection-API hat.

Die Frage nach Legalität bleibt auch. Es gibt einen Grund für diese Grenze. Konsultieren Sie einen Anwalt, wenn Sie betroffen sind.

Wenn möglich, versuchen, es zu halten, um eine 128-Bit-Schlüssel. Selbst wenn man das Gesetz von Moore in Betracht zieht, würde die Auflösung von 128-Bit-AES Milliarden auf Milliarden von Jahren kosten. Längere Schlüssel bieten in der realen Welt keinen Vorteil - insbesondere, wenn die Schlüssel aus Passwörtern abgeleitet sind, die sowieso nicht annähernd 256 Bit Entropie haben.

+0

Champion. Werde es morgen ausprobieren. Es gibt noch Hoffnung;) – drew

+0

@ntoskml Kein Glück hier. Setzt die Klassenvariable auf ** ** JceSecurity aber nicht keysize ermöglichen> = 128 Java-Version: ** SE 1.7.0_21 ** – drew

+0

@drew Das ist seltsam, weil es für uns in allen Versionen von Arbeiten Java 6 und 7 haben wir getestet. Wir haben auch keine Berichte von Benutzern gehört. In der Tat, auch [Java 8] (http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/javax/crypto/JceSecurity.java) hat immer noch die gleiche Klasse und Feld. Haben Sie diese Methode vor dem Laden von Kryptoklassen aufgerufen? Versuchen Sie es von einem statischen Initializer aus aufzurufen. Ansonsten klingt es wie ein Problem mit Applets. Vielleicht eine Sicherheitsrichtlinie oder Klassenladertrick? Bitte versuchen Sie es in einer Nicht-Applet-Umgebung, um andere Probleme auszuschließen. – ntoskrnl

2

Sie entweder mit der schwachen Verschlüsselung oder einen potentiell problematischen Schritt für Anwender stecken wenn Sie an der SunJCE bleiben.

Es gibt offensichtlich kein Problem beim Importieren einer AES-Bibliothek, es gibt nur ein Problem bei der Verwendung einer Instanz von Cipher. Wenn Sie eine bestimmte Software haben, die nicht von JCA abhängig ist, können Sie sie zum Beispiel neu schreiben, um die leichte Krypto-API von Bouncy Castle zu verwenden.

Beachten Sie, dass viele andere Teile der Bouncy API selbst von der JCE abhängig sind. Die Lightweight-API ist auch schwieriger zu verwenden und weniger dokumentiert/getestet als die SunJCE.

Die Bouncy Castle leichte API ist auch ziemlich groß. Es enthält viele Funktionen, die Sie nicht benötigen. Es ist also wahrscheinlich zu groß für dein Applet. Wenn es ist, würde ich Ihnen raten, eine neue Bibliothek zu erstellen, die nur die spezifischen Klassen enthält, die Sie von Bouncy Castle benötigen. Die Hüpfburg ist zum Glück sehr großzügig lizenziert. Solange Sie die Copyright-Vermerke etc. beibehalten, können Sie sie leicht trennen.

+0

Hat der BC-Lösung beinhalten viel aufblasen. Ein Applet zu sein ist ein bisschen restriktiv. Ich habe versucht, es bisher zu vermeiden. – drew

+0

Wäre das die "JCE mit Provider und Lightweight API" in [Bouncycastle neuesten Releases] (http://www.bouncycastle.org/latest_releases.html), die Sie für diese Funktionalität meinen? Das ist etwa 7,7 Megabyte als Zip. Die "Lightweight API" daneben ist ein 6,6-Megapixel-Zip. Ich überlege gerade, wieviele zusätzliche Bytes es für den Applet-Benutzer bedeuten wird. BTW - bezüglich des Problems (gut, näher) .. Was genau tut dieses Applet genau? Warum die starke (?) Verschlüsselung? –

+0

Ich möchte ein PKCS # 12-Schlüsselspeicherkennwort zwischen Sitzungen im Browserkontext verschlüsseln und speichern. Der Schlüsselspeicherzugriff wird verwendet, um Uploads zu signieren und entschlüsselte Token zu entschlüsseln (separate Funktionen). Andernfalls muss der Benutzer möglicherweise sein Passwort wiederholt eingeben. – drew