我有解密的问题(也许错了加密,太)与RSA在Java中的数据。 我想在字符串一些更多的信息加密的公钥,然后解密此公钥和与它加密的东西(我用的2048 RSA):错误RSA数据爪哇解密:javax.crypto.BadPaddingException:解密错误
加密:
public void saveExportToFile(String fileName, BigInteger mod, BigInteger exp, String info, PublicKey puk) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(baos));
try {
oout.writeObject(mod);
oout.writeObject(exp);
oout.writeChars(info);
oout.close();
baos.close();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, puk);
FileOutputStream fos = new FileOutputStream(new File(fileName));
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] data = baos.toByteArray();
int i = 0;
byte[] buffer = new byte[128];
byte[] cipherData = null;
while (i < data.length) {
if (i+128 >= data.length) {
buffer = new byte[data.length - i];
System.arraycopy(data, i, buffer, 0, data.length - i);
cipherData = cipher.doFinal(buffer);
bos.write(cipherData);
} else {
System.arraycopy(data, i, buffer, 0, 128);
cipherData = cipher.doFinal(buffer);
bos.write(cipherData);
}
i += 128;
}
bos.close();
} catch (Exception e) {
throw new IOException("Unexpected error", e);
}
}
解密:
public void getDataFromRSA(String sendname, PrivateKey privateKey) {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(sendname)));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int length = 0;
int allLength = 0;
byte[] buffer = new byte[128];
byte[] bufferAC = null;
byte[] outData = null;
byte[] allData = null;
byte[] tmpData = null;
while ((length = bis.read(buffer)) != -1) {
if (length < 128) {
bufferAC = new byte[length];
System.arraycopy(buffer, 0, bufferAC, 0, length);
outData = cipher.doFinal(bufferAC);
} else {
outData = cipher.doFinal(buffer); // HERE IS THE ERROR
}
allLength += outData.length;
tmpData = allData;
allData = new byte[allLength];
System.arraycopy(tmpData, 0, allData, 0, tmpData.length);
System.arraycopy(outData, 0, allData, tmpData.length, outData.length);
}
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | ClassNotFoundException | InvalidKeySpecException e) {
e.printStackTrace();
}
}
编辑 OK,看来我不知道密码,因为我以为多。我只想使用RSA(如果可能的话),因为我不需要多次传输信息(信息大小各不相同)。我已经编辑加密这样的:
int i = 0;
byte[] buffer = new byte[245];
byte[] cipherData = null;
while (i < data.length) {
if (i+245 >= data.length) {
buffer = new byte[data.length - i];
System.arraycopy(data, i, buffer, 0, data.length - i);
} else {
System.arraycopy(data, i, buffer, 0, 245);
}
cipherData = cipher.update(buffer);
bos.write(cipherData);
i += 245;
}
bos.write(cipher.doFinal()); // HERE IS THE ERROR
bos.close();
现在我得到javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
(缓冲区大小尝试了较低的值)。是否因为数据长度不是块大小的倍数?这可以解决吗?感谢您的回答。
您不应该使用RSA作为分组密码。在你的方案中,攻击者可以简单地将先前的块插入密码中的任何位置,而无需在解密期间发现它。混合加密/解密并不难,你为什么不努力做正确的事情? – 2014-09-06 16:46:41
对于你当前的问题:RSA有填充开销,你应该把最多245个字节和每256个字节解密(11字节开销)。如果必须的话,在带有245字节加密缓冲区和256字节解密*输入*缓冲区的循环中使用doFinal。请注意,这不会解决您的协议,只是您当前的实施。 – 2014-09-06 16:50:07
谢谢,我现在使用混合加密技术现在没有问题 – d3im 2014-09-07 19:26:55