实际上,我为此也从互联网和stackoverflow中进行了大量搜索,
最初,我在加密和解密中不使用填充,
但最后我从这里得到了解决方案
https://stackoverflow.com/a/10775577/1115788
并且我用填充作为AES / CBC / PKCS5Padding更新了我的代码,并且出现了相同的错误,并且最后一个块未解密…
我最近两天正在为此工作,但未找到解决方案
我的密码:
package mani.droid.browsedropbox;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Crypter {
Cipher encipher;
Cipher decipher;
CipherInputStream cis;
CipherOutputStream cos;
FileInputStream fis;
byte[] ivbytes = new byte[]{(byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p'};
IvParameterSpec iv = new IvParameterSpec(ivbytes);
public boolean enCrypt(String key, InputStream is, OutputStream os)
{
try {
byte[] encoded = new BigInteger(key, 16).toByteArray();
SecretKey seckey = new SecretKeySpec(encoded, "AES");
encipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
encipher.init(Cipher.ENCRYPT_MODE, seckey, iv);
cis = new CipherInputStream(is, encipher);
copyByte(cis, os);
return true;
}
catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public boolean deCrypt(String key, InputStream is, OutputStream os)
{
try {
byte[] encoded = new BigInteger(key, 16).toByteArray();
SecretKey seckey = new SecretKeySpec(encoded, "AES");
encipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
encipher.init(Cipher.DECRYPT_MODE, seckey, iv);
cos = new CipherOutputStream(os, encipher);
copyByte(is, cos);
//cos.close();
return true;
}
catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
public void copyByte(InputStream is, OutputStream os) throws IOException
{
byte[] buf = new byte[8192];
int numbytes;
while((numbytes = is.read(buf)) != -1)
{
os.write(buf, 0, numbytes);
os.flush();
}
os.close();
is.close();
}
}
我遇到了完全相同的问题。可接受的解决方案之所以有效,是因为您使用了不需要填充的加密模式,但这不是解决与加密有关的问题的方法。
根据CipherOutputStream
文档,必须调用close()方法才能正确完成加密(即,添加了填充块)。
此方法调用封装密码对象的doFinal方法,这将导致处理由封装密码缓冲的所有字节。通过调用此输出流的flush方法来写出结果。
此方法将封装的密码对象重置为其初始状态,并调用基础输出流的close方法。
如果要在调用CipherOutputStream.close()方法后仍保持OutputStream打开,则可以将OutputStream包装到不关闭它的流中。例如:
public class NotClosingOutputStream extends OutputStream {
private final OutputStream os;
public NotClosingOutputStream(OutputStream os) {
this.os = os;
}
@Override
public void write(int b) throws IOException {
os.write(b);
}
@Override
public void close() throws IOException {
// not closing the stream.
}
@Override
public void flush() throws IOException {
os.flush();
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
os.write(buffer, offset, count);
}
@Override
public void write(byte[] buffer) throws IOException {
os.write(buffer);
}
}
然后,您可以使用:
...
cos = new CipherOutputStream(new NotClosingOutputStream(os), encipher);
copyByte(is, cos);
cos.close();
...
请注意,os
流不会关闭,您需要在适当时自行完成。
我使用JavaAPI生成128bit密钥。下面是我使用的算法: 我可以通过这些方法轻松地使用secretKey加密和解密消息。由于Java默认使用128bit AES加密,因此它使用SHA1生成原始密钥的哈希,并将哈希的前16字节用作AES中的密钥。然后以十六进制格式转储IV和密文。 但是,它返回一个空字符串。
我有一些问题,解密文本的CryptoJS已经用Java加密。解密应使用AES/CBC/PKCS5Padding完成。加密的字符串是base64编码的,我在尝试解密字符串之前对其进行解码。 这就是Java代码的样子:
我正在加密字符串并将其存储在客户端的cookie中。。但是,当我从js向java代码发送完全加密的字符串时,它给出了前面提到的异常。 我用于加密和解密的代码是: 你能告诉我问题是什么吗??我尝试过stackoverflow上提到的解决方案。com和其他一些解决方案,但都不起作用。。我收到这个错误是因为我将加密字符串发送到JS,而它正在更改字符串的填充吗?
我目前使用< code > AES/CBC/PKCS 5 Padding 对Java文件进行加密,密钥大小为256字节,但在搜索时,我在stack exchange PKCS # 5-PKCS # 7 Padding上发现了它, PKCS#5填充是8字节块大小的PKCS#7填充的子集 所以我想知道 > < li >对于上述配置,< code > AES/CBC/pkcs 7 padding 的性能
我正在加密我的Android应用程序中的一些数据,然后这些数据被发送到一个PHP页面进行解密和处理。 这有帮助吗?