[英]RSA keyblock wrapper: javax.crypto.BadPaddingException: Decryption error
在更大的应用程序中,其他的事情-我需要加密和解密文件。 因此,我一直在研究并实现了这两个核心功能,这些功能基本上使用RSA密钥来包装用于加密文件的随机AES密钥。 对称密钥和iv被写入文件的开头。
我在下面的解密功能部分遇到异常(“ javax.crypto.BadPaddingException:解密错误”)。 在unpackKeyandIV行上-doFinal。 具体来说,该行是异常点:Object [] keyIv = unpackKeyAndIV(xCipher.doFinal(keyBlock));
我检查并重新制作了RSA密钥对。 我还检查了keyBlock的保存/加载。
我的直觉是问题与我写/读keyBlock或编码有关吗?
一个目标是使RSA / AES实例尽可能通用,以免需要Bouncy Castle或额外的Java安全性无限强度扩展。
关于我可能会出错的任何想法。
提前致谢。 [最终更新:以下代码有效。 错误传递了损坏的privKey]
// RSA_INSTANCE = "RSA";
// ASSYM_CRYPTO_STR = 1024;
// SYM_CRYPTO_STR = 128;
// SYM_CRYPTO = "AES";
// AES_INSTANCE = "AES/CTR/NoPadding";
//
// File in = plain input file
// File out = encrypted output file
// Key pubKey = public Key (that wraps a random AES key)
public static void encryptFile(File in, File out, Key pubKey) throws Exception {
FileInputStream fin;
FileOutputStream fout;
int nread = 0;
byte[] inbuf = new byte[1024];
fout = new FileOutputStream(out);
fin = new FileInputStream(in);
SecureRandom random = new SecureRandom();
// symmetric wrapping
Key sKey = createKeyForAES(Config.SYM_CRYPTO_STR, random);
IvParameterSpec sIvSpec = createCtrIvForAES(0, random);
// encrypt symmetric key with RSA/pub key
Cipher xCipher = Cipher.getInstance(Config.RSA_INSTANCE);
xCipher.init(Cipher.ENCRYPT_MODE, pubKey, random);
byte[] keyBlock = xCipher.doFinal(packKeyAndIv(sKey, sIvSpec));
fout.write(keyBlock);
// encrypt data with symmetric key
Cipher sCipher = Cipher.getInstance(Config.AES_INSTANCE);
sCipher.init(Cipher.ENCRYPT_MODE, sKey, sIvSpec);
// Now read our file and encrypt it.
while((nread = fin.read(inbuf)) > 0) {
fout.write(sCipher.update(inbuf, 0, nread)); // cannot be null, by construction
}
// NB doFinal() cannot return null, but can return a zero-length array, which is benign below.
fout.write(sCipher.doFinal());
fout.flush();
fin.close();
fout.close();
}
// Decrypt File
public static void decryptFile(File in, File out, Key privKey) throws Exception {
FileInputStream fin;
FileOutputStream fout;
int nread = 0;
byte[] inbuf = new byte[1024];
fout = new FileOutputStream(out);
fin = new FileInputStream(in);
byte[] keyBlock = new byte[128];
nread = fin.read(keyBlock);
Cipher xCipher = Cipher.getInstance(Config.RSA_INSTANCE);
Cipher sCipher = Cipher.getInstance(Config.AES_INSTANCE);
// symmetric key/iv unwrapping step
xCipher.init(Cipher.DECRYPT_MODE, privKey);
Object[] keyIv = unpackKeyAndIV(xCipher.doFinal(keyBlock));
// decryption step
sCipher.init(Cipher.DECRYPT_MODE, (Key)keyIv[0], (IvParameterSpec)keyIv[1]);
while((nread = fin.read(inbuf)) >0) {
fout.write(sCipher.update(inbuf,0,nread));
}
fout.write(sCipher.doFinal());
fout.flush();
fin.close();
fout.close();
}
public static byte[] packKeyAndIv(Key key, IvParameterSpec ivSpec) throws IOException {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
bOut.write(ivSpec.getIV());
bOut.write(key.getEncoded());
return bOut.toByteArray();
}
public static Object[] unpackKeyAndIV(byte[] data) {
byte[] keyD = new byte[16];
byte[] iv = new byte[data.length - 16];
return new Object[] {
new SecretKeySpec(data, 16, data.length - 16, "AES"),
new IvParameterSpec(data, 0, 16)
};
}
每个编辑和评论。 错误是将损坏的privKey传递给了解密函数。 上面的代码工作正常。
尝试在您的构造函数下添加以下内容-
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.