我正在编写一个从控制台输入的程序 - 一个zip文件的名称,一个zip文件的名称包含从第一个zip生成的加密文件和一个包含公钥的文件。每次关闭流时都会收到异常:
Exception in thread "main" java.util.zip.ZipException: invalid entry size (expected 11 but got 128 bytes)
at java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:288)
at java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:361)
at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:238)
at java.util.zip.ZipOutputStream.close(ZipOutputStream.java:378)
at javax.crypto.CipherOutputStream.close(CipherOutputStream.java:217)
at com.Main.main(Main.java:107)
我该如何解决这个问题?代码如下:
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Enumeration;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
public class Main {
public final static int BUFFER_SIZE = 1024;
public static String getPublicKeyString(String fileName){
String key = new String();
try {
BufferedReader buf = new BufferedReader(new FileReader(fileName));
key = buf.readLine();
} catch ( IOException e) {
e.printStackTrace();
}
return key.trim();
}
public static PublicKey makePublicKey(String stored) throws GeneralSecurityException {
byte[] data = Base64.getDecoder().decode(stored);//Base64.decode(keyBytes, Base64.DEFAULT);
X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
KeyFactory fact = KeyFactory.getInstance("RSA");
return fact.generatePublic(spec);
}
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
System.out.println("Enter type of operation:");
String line = scan.nextLine();
if(line.equals("encrypt")){
// Reading from console
System.out.println("Enter name of original ZIP file:");
String originalZipFileName = scan.nextLine();
System.out.println("Enter name of new ZIP file:");
String newZipFileName = scan.nextLine();
System.out.println("Enter name of file containg public key:");
String publicKeyFileName = scan.nextLine();
String publicKey = getPublicKeyString(publicKeyFileName);
// Declaration
ZipFile originalZipFile = new ZipFile(originalZipFileName);
byte[] buffer = new byte[BUFFER_SIZE];
ZipOutputStream newZipFile = new ZipOutputStream(new FileOutputStream(newZipFileName));
Enumeration<? extends ZipEntry> zipEntries = originalZipFile.entries();
//
PublicKey key = makePublicKey(publicKey);
//System.out.println(key.toString());
//
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
while(zipEntries.hasMoreElements()){
ZipEntry entry = zipEntries.nextElement();
ZipEntry copy = new ZipEntry(entry);
newZipFile.putNextEntry(copy);
int read;
InputStream input = originalZipFile.getInputStream(entry);
CipherOutputStream cos = new CipherOutputStream(newZipFile, cipher);
while((read = input.read(buffer)) != -1){
cos.write(buffer, 0, read);
}
input.close();
cos.close();
newZipFile.closeEntry();
}
}
}
}
答案 0 :(得分:0)
RSA只能用于加密相对少量的数据,减去RSA模数的字节大小。当您执行cos.close()
时,被包装的密码对象会调用其doFinal()
方法生成IllegalBlockSizeException
,CipherOutputStream
会被ZipOutputStream
静默吞下。但是,由于没有数据通过密码对象导致{{1}}混乱,因此它在关闭时抛出异常。
您无法按照自己的方式使用RSA。