AES mit 32byte Key

hasso

Mitglied
Hallo,

nachdem mir mein AES Cipher-Objekt ständig um die Ohren geflogen ist (illegal key size) wenn ich versuchte es mit einem 32byte großen key zu initialisieren hab ich mich mal schlau gemacht und festgestellt das Java im normalen standard JDK nur maximal 16byte große keys unterstützt.

Als Lösungen werden angeboten irgendwelche Files nachzuinstallieren (was ich nicht kann) oder einen Provider zu benutzen der mehr unterstützt. Da überall BouncyCastle als Provider empfohlen wird hab ich mir die Bibliothek runtergeladen.

Java:
private void jButton12ActionPerformed(java.awt.event.ActionEvent evt) {
        System.out.println("KEY TESTS");
        try
        {
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/NOPADDING", "BC");
            byte[] key = new byte[]{(byte)0xB1, (byte)0xD4, (byte)0xE8, (byte)0x7B, (byte)0x12, (byte)0x8D, (byte)0xF2, (byte)0x6A,
                                    (byte)0x3C, (byte)0x30, (byte)0x84, (byte)0x0B, (byte)0xA0, (byte)0xFC, (byte)0xE3, (byte)0x64,
                                    (byte)0x03, (byte)0x55, (byte)0x04, (byte)0x0A, (byte)0x13, (byte)0x0A, (byte)0x53, (byte)0x69,
                                    (byte)0x65, (byte)0x6D, (byte)0x65, (byte)0x6E, (byte)0x73, (byte)0x20, (byte)0x41, (byte)0x47};
            byte[] data = new byte[]{(byte)0x03, (byte)0x55, (byte)0x04, (byte)0x0A, (byte)0x13, (byte)0x0A, (byte)0x53, (byte)0x69,
                                     (byte)0x65, (byte)0x6D, (byte)0x65, (byte)0x6E, (byte)0x73, (byte)0x20, (byte)0x41, (byte)0x47};
            byte[] iv = new byte[]{(byte)0x38, (byte)0xF1, (byte)0x00, (byte)0x95, (byte)0x2C, (byte)0x8E, (byte)0x14, (byte)0x49,
                                   (byte)0xB3, (byte)0x61, (byte)0x20, (byte)0x49, (byte)0x26, (byte)0x3F, (byte)0xAC, (byte)0xCC};
            SecretKeySpec sks = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, sks, new IvParameterSpec(iv));
            byte[] enc = cipher.doFinal(data);
            System.out.println("DONE");
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

Er fliegt aber nach wie vor beim Initialisieren des Cipher-Objekts raus mit der Meldung "illegal key size".
Kennt sich da jemand aus ? Wie mache ich das richtig ?

Grüße
 

hasso

Mitglied
Ah, da hab ich gar nicht mehr reingeschaut weil ich woanders gelesen hatte das man entweder diese Policys installieren muss ODER einen Provider benutzen (da der Provider die schon hätte).

Dann hat sich die Frage erledigt, dann muss ich doch nen Antrag stellen auf dem PC was installieren zu dürfen ;(

Danke für die Antwort.

Grüße
 
G

Gast2

Gast
Dazu musst du nichts "installieren", nur zwei Jar Files kopieren:

3) Install the unlimited strength policy JAR files.

In case you later decide to revert to the original "strong" but
limited policy versions, first make a copy of the original JCE
policy files (US_export_policy.jar and local_policy.jar). Then
replace the strong policy files with the unlimited strength
versions extracted in the previous step.

The standard place for JCE jurisdiction policy JAR files is:

<java-home>/lib/security [Unix]
<java-home>\lib\security [Windows]
 
S

SlaterB

Gast
nebenbei ganz allgemein:
Code der Form
Java:
byte[] key = new byte[]{(byte)0xB1, (byte)0xD4, (byte)0xE8, (byte)0x7B, (byte)0x12 ...
ist unnötig, falls das nicht als besonders schick empfunden wird,
man kann eine Hilfsmethode erstellen die die richtigen Datentypen akzeptiert und intern alles passend umwandelt:
Java:
byte[] key = create(0xB1, 0xD4, 0xE8, 0x7B, 0x12 ...
also spätestens seit Vargargs
Varargs

im Normalfall wäre es immer noch besser, ein int[] oder so zu befüllen und das dann zu übernehmen,
oder einen String, dann gleich ohne 0x, falls nicht wiederum erwünscht,
"B1, D4, E8, 7B, 12" und parsen,

tausend Mal [c](byte)[/c] usw. muss in keinem Code stehen
 

hasso

Mitglied
Ja, ich weiß, aber ich muss dazu auf Installationsverzeichnisse zugreifen und hab darauf leider mit meinen Berechtigungen keinen Zugriff. Daher hatte ich gehofft ich komm drum rum, hätte Zeit gespart.

Grüße
 
T

tröööt

Gast
dachte eigentlich immer das BC auch ohne policies AES256 kann .. aber naja ...

@TO
bei krypto-verfahren nennt man in der regel die BIT-zahl ... nicht die BYTE-zahl ... also AES128/192/256 statt AES16/24/32 ...
das hat sich so eingebürgert ... und das solltest du auch übernhemen ...

weiterhin : du willst mit CBC eine stream-chiffre aber nutzt NOPADDING ? da wird dir einiges um die ohren fliegen ... nutze besser CBC/PKCS5PADDING ... NOPADDING ist eher für ECB gedacht ... (wobei auch hier padding nicht schaden kann)

und schlussendlich die hauptfrage : WARUM unbedingt AES256 ? AES128 reicht dicke aus und läuft unter jeder VM ... wenns nur für dich sein muss ... naja mein gott ... dann ist kryptografie eh völlig egal .. aber wenn du deinen code verteilen willst solltest du dich an standards halten ... und AES ist nun mal standardmäßig 128/128 ...

@Slater
hmm ... ohne cast fliegt ein ERROR ... geht also nicht ...
und mit der helper-methode den cast nur an ne andere stelle verschieben ist auch keine lösung ...
und Byte.parse() mit werten über 0x7F löst ne exception aus ...
also wirklich sinnvoll und einfach dierekt BYTE-werte im code zu haben und diese auch als "byte" nutzen zu können ohne irgendwelche tricks und casts und und und gibt es nicht ...
ansonsten poste doch mal dein beispiel ... vielleicht hilft es nicht nur TO ...
 
S

SlaterB

Gast
> und mit der helper-methode den cast nur an ne andere stelle verschieben ist auch keine lösung ...

Verschieben an sich ist durchaus schon eine Lösung,
vor allem aber wenn man mit Schleifen usw. und Mehrfachverwendung riesige Mengen auf wenige reduziert

bei Helfer-Methoden ist die Länge auch praktisch egal,
eine ArrayList mag unnötige 300 Zeilen lang sein, wenn dann aber das Hauptprogramm von 20 auf 3 Zeilen schmilzt, ist das äußerst komfortabel

die Varianten, die ich gemeint hatte:
Java:
public class Test2
{

    public static void main(String[] args)
    {
        byte[] key1 = new byte[] {(byte)0xB1, (byte)0xD4, (byte)0xE8, (byte)0x7B}; // 'such die Infos zwischen der Syntax'
        byte[] key2 = create(0xB1, 0xD4, 0xE8, 0x7B);
        byte[] key3 = create(new int[] {0xB1, 0xD4, 0xE8, 0x7B}); // falls kein Varargs
        byte[] key4 = parse("B1, D4, E8, 7B"); // für reine Daten durchaus denkbar, manche nehmen Textdateien..

        for (int i = 0; i < key1.length; i++)   {
            System.out.println("i: " + i + ", " + key1[i] + ", " + 
               key2[i] + ", " + key3[i] + ", " + key4[i]);
        }
    }

    public static byte[] create(int... values) {
        byte[] b = new byte[values.length];
        for (int i = 0; i < b.length; i++)   {
            b[i] = (byte)values[i];
        }
        return b;
    }

    public static byte[] parse(String values)
    {
        String[] parts = values.split(", ");
        byte[] b = new byte[parts.length];
        for (int i = 0; i < b.length; i++)  {
            b[i] = (byte)Integer.parseInt(parts[i], 16); // klappt für alle bytes
        }
        return b;
    }
}
 

Oben