2010-11-26 44 views
0

我正在測試java applet中的AES 256。它工作得很好,如果我解碼字節[]我得到的代碼。我在編碼的字符串文本框中以二進制格式打印字節。如果我把這個字符串解碼,我會得到一個異常Given final block not properly padded。有什麼問題?Java25中的AES256錯誤

我的代碼如下


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

你試圖通過你直接加密到解密的程序之後得到的字節數組?也許你正在通過BigDecimal和二進制字符串表示方式丟失一些東西...... – 2010-11-26 13:11:03

回答

3

這就是問題所在:

String originalString = new String(original); 

你把不透明的二進制數據,並試圖將其解釋爲,如果它是一個有效的文本字符串。它幾乎肯定不會。此外,你使用系統默認編碼轉換它,這幾乎是從來沒有一個好主意。

要表示文本中的任意二進制數據,最好使用base64對其進行編碼和解碼。或者,使用十六進制 - 你已經有了將二進制數據轉換爲十六進制的方式,所以你可能想使用它。它比base64稍長一些,但你可能會發現它更容易處理。

1

您應該用一些合適的TEXT格式(如十六進制編碼或base64)編碼byte[] encrypted。要解密,您再次從文本表示再次傳遞到byte[]

的問題是圍繞這些線:

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

BigInteger bi = new BigInteger(encrypted); 

如果你必須將其編碼爲使用,上述編碼的一個字符串,例如,。看看這個任務的commons-codec。

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