2010-11-26 42 views
0

Je suis en train de tester AES 256 dans une applet Java. Cela fonctionne très bien si je décode l'octet [] je reçois dans le code. J'imprime l'octet au format binaire dans la zone de texte codée. si je prends cette chaîne et décode, je reçois une exception Given final block not properly padded. Quel est le problème?AES256 en erreur Java

mon code suit


public class TestApplet extends Applet { 
Label lblKey = new Label("Key"); 
TextField inputLineKey = new TextField(15); 
Label lblString = new Label("Value"); 
TextField inputLineString = new TextField(15); 
Label lblStringEncoded = new Label("Encoded Value"); 
TextField inputLineStringEncoded = new TextField(15); 
Label lblStringDecoded = new Label("Decoded Value"); 
TextField inputLineStringDecoded = new TextField(15); 
Button encodeButton = new Button("Test Encrypt"); 
Button decodeButton = new Button("Test Decrypt"); 

public TestApplet() { 
    add(inputLineKey); 
    add(lblKey); 
    add(inputLineString); 
    add(lblString); 
    add(inputLineStringEncoded); 
    add(lblStringEncoded); 
    add(inputLineStringDecoded); 
    add(lblStringDecoded); 
    add(encodeButton); 
    add(decodeButton); 
    // inputLine.addActionListener(new MyActionListener()); 
} 

/** 
    * Turns array of bytes into string 
    * 
    * @param buf 
    *   Array of bytes to convert to hex string 
    * @return Generated hex string 
    */ 
public static String asHex(byte buf[]) { 
    StringBuffer strbuf = new StringBuffer(buf.length * 2); 
    int i; 

    for (i = 0; i < buf.length; i++) { 
    if (((int) buf[i] & 0xff) < 0x10) 
    strbuf.append("0"); 

    strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); 
    } 

    return strbuf.toString(); 
} 

public boolean action(Event e, Object args) { 

    // so do something! 

    // /////////////////////// 
    try { 
    String message = "This is just an example"; 

    // Get the KeyGenerator 

    KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
    kgen.init(128); // 192 and 256 bits may not be available 

    // Generate the secret key specs. 
    SecretKey skey = kgen.generateKey(); 
    byte[] raw = skey.getEncoded(); 

    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 

    // Instantiate the cipher 

    Cipher cipher = Cipher.getInstance("AES"); 

    if (e.target == encodeButton) { // User has clicked on encrypt 
      // button 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 

    byte[] encrypted = cipher.doFinal((inputLineString.getText() 
     .length() == 0 ? message : inputLineString.getText()) 
     .getBytes()); 
    // System.out.println("encrypted string: " + asHex(encrypted)); 

    cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
    byte[] original = cipher.doFinal(encrypted); 
    String originalString = new String(original); 
    // System.out.println("Original string: " + 
    // originalString + " " + asHex(original)); 

    // Create a BigInteger using the byte array 
    BigInteger bi = new BigInteger(encrypted); 

    inputLineStringEncoded.setText(bi.toString(2)); // (new String(encrypted)); 
    inputLineStringDecoded.setText(originalString); 
    } 

    if (e.target == decodeButton) { // User has clicked on decrypt 
      // button 
    // cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
    // 
    // byte[] encrypted = cipher.doFinal((inputLineString.getText() 
    // .length() == 0 ? message : inputLineString.getText()) 
    // .getBytes()); 
    // // System.out.println("encrypted string: " + asHex(encrypted)); 

    cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
    // Parse binary string 
    BigInteger bi = new BigInteger(inputLineStringEncoded 
     .getText(), 2); 

    byte[] original = cipher.doFinal(bi.toByteArray()); 
    String originalString = new String(original); 
    // System.out.println("Original string: " + 
    // originalString + " " + asHex(original)); 
    inputLineString.setText(originalString); 
    inputLineStringDecoded.setText(originalString); 
    } 

    } catch (Exception exc) { 
    inputLineStringEncoded.setText(exc.getMessage()); 
    } 
    return true; // Yes, we do need this! 
} 

class MyActionListener implements ActionListener { 
    public void actionPerformed(ActionEvent event) { 
    } 
} 
} 
________________________________ 
+0

Avez-vous essayé passer le tableau d'octets que vous obtenez après le chiffrement directement à votre routine de décryptage? Peut-être perdez-vous quelque chose en passant par une représentation BigDecimal et String du binaire ... –

Répondre

3

C'est le problème:

String originalString = new String(original); 

Vous prenez des données binaires opaques et d'essayer de l'interpréter comme si elle était une chaîne de texte valide. Ce ne sera certainement pas le cas. En outre, vous le convertissez en utilisant l'encodage par défaut du système, qui est presque jamais une bonne idée.

Pour représenter des données binaires arbitraires dans un texte, il est préférable d'utiliser base64 pour le coder et le décoder. Alternativement, utilisez hex - vous avez déjà un moyen de convertir les données binaires en hexadécimal, donc vous pourriez vouloir l'utiliser. C'est légèrement plus long que base64, mais vous pouvez le trouver plus facile à traiter.

1

Vous devez encoder byte[] encrypted dans un format TEXT approprié, tel que hexode ou base64. Pour déchiffrer, vous passez à nouveau de la représentation textuelle à byte[].

Le problème est autour de ces lignes:

byte[] original = cipher.doFinal(bi.toByteArray()); 
String originalString = new String(original); 

et

BigInteger bi = new BigInteger(encrypted); 

Si vous devez encoder une chaîne en utilisant, par exemple, l'un des encodages ci-dessus. Jetez un oeil à commons-codec pour cette tâche.

http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html