java 中的 AES256 错误
我正在 java 小程序中测试 AES 256。如果我解码代码中得到的 byte[] ,它就可以正常工作。我在编码字符串文本框中以二进制格式打印字节。如果我获取该字符串并进行解码,我会得到一个异常 Given Final block notpropedly 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) {
}
}
}
________________________________
i am testing AES 256 in a java applet. It works just fine if i decode the byte[] i get in the code. I print the byte in binary format in encoded string textbox. if i take that string and decode, I get an exception Given final block not properly padded
. What's the problem?
my code follows
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) {
}
}
}
________________________________
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是问题所在:
您正在获取不透明的二进制数据并尝试将其解释为有效的文本字符串。几乎肯定不会。此外,您使用系统默认编码对其进行转换,这几乎永远不是一个好主意。
要在文本中表示任意二进制数据,最好使用 Base64 对其进行编码和解码。或者,使用十六进制 - 您已经有了将二进制数据转换为十六进制的方法,因此您可能需要使用它。它比 base64 稍长,但您可能会发现它更容易处理。
This is the problem:
You're taking opaque binary data and trying to interpret it as if it were a valid text string. It almost certainly won't be. Furthermore, you're converting it using the system default encoding, which is almost never a good idea.
To represent arbitrary binary data in text, it's best to use base64 to encode and decode it. Alternatively, use hex - you've already got a way of converting binary data to hex, so you might want to use that. It's slightly longer than base64, but you may find it easier to deal with.
您应该以某种合适的文本格式(例如十六进制编码或 base64)对
byte[]加密
进行编码。要解密,您需要再次从文本表示形式传递到byte[]
。问题出在以下几行:
以及
必须使用例如上述编码之一将其编码为字符串。查看该任务的 commons-codec。
http://commons.apache.org/codec /apidocs/org/apache/commons/codec/binary/Base64.html
You should encode
byte[] encrypted
in some suitable TEXT format like hex encode or base64. To decrypt you pass from text representation again tobyte[]
.The problem is around these lines:
and
Where you must encode it to a string using, for example, one of the above encodings. Take a look at commons-codec for that task.
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Base64.html