约瑟夫是对的。
使用默认参数创建密码时,默认密码为“ RSA / ECB /
PKCS1Padding”。如果您不喜欢令人讨厌的惊喜,则应明确指定填充。因为其他安全提供程序可能具有不同的默认参数。而且您永远不会事先知道每个特定的JRE具有哪些安全设置。
因此,PKCS1填充将11字节添加到原始数据中,从117字节增加到128字节。您应该考虑到这些数字是特定于1024位RSA密钥(这在一定程度上是安全的),并且对于较长的密钥将有所不同。由于要从文件加载密钥,请考虑检查其长度。
@Testpublic void testPadding() throws Exception { SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024, random); KeyPair keyPair = keyGen.generateKeyPair(); byte[] plaintext = new byte[117]; random.nextBytes(plaintext); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic()); byte[] ciphertext = cipher.doFinal(plaintext); System.out.println(plaintext.length + " becomes " + ciphertext.length);}此打印
117 becomes 128
最后,考虑使用AES代替RSA进行文件加密。
因此,要解决此问题,您需要使用大小为公共密钥长度的缓冲区-加密使用11(117),解密使用公共密钥大小(128)。
更改
outputFile.write(cipher.doFinal(buffer), 0, read);
至
outputFile.write(cipher.doFinal(buffer));
因为缓冲区读取为117个字节,doFinal结果的大小为128个字节。
另外,您需要缓冲输入流。从文件读取时,有时可能会很慢,然后InputStream读取的数据将少于缓冲区可能包含的数据。通过使用BufferedInputStream,可以确保在读取调用返回之前有足够的数据。但是,对于解密而言,拥有完整的数据块至关重要
InputStream inputEntry = new BufferedInputStream(originalZipFile.getInputStream(entry));



