繁体   English   中英

Java中的AES256错误

[英]AES256 in java error

我正在Java小程序中测试AES 256。 如果我将代码中的byte []解码,则效果很好。 我在编码的字符串文本框中以二进制格式打印字节。 如果我采用该字符串进行解码,则会得到异常,因为Given final block not properly padded 有什么问题?

我的代码如下


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) {
  }
 }
}
________________________________

这就是问题:

String originalString = new String(original);

您正在获取不透明的二进制数据,并试图将其解释为有效的文本字符串。 几乎可以肯定不会。 此外,您正在使用系统默认编码对其进行转换,这几乎从来不是一个好主意。

为了表示文本中的任意二进制数据,最好使用base64对其进行编码和解码。 另外,也可以使用十六进制-您已经有了将二进制数据转换为十六进制的方法,因此您可能想使用它。 它比base64稍长,但是您可能会发现它更容易处理。

您应该以某种合适的TEXT格式(例如十六进制编码或base64)对byte[] encrypted 要解密,请再次从文本表示形式传递给byte[]

问题在于以下几行:

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

BigInteger bi = new BigInteger(encrypted);

您必须使用例如上述编码之一将其编码为字符串。 看一下该任务的commons编解码器。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM