我试图使用AES-256加密密码加密一个压缩文件.下面是我正在运行的代码。
import java.io.*;
import java.security.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void encryptAndClose(FileInputStream fis, FileOutputStream fos)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("1234567890123456".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream for encoding
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
//wrap output with buffer stream
BufferedOutputStream bos = new BufferedOutputStream(cos);
//wrap input with buffer stream
BufferedInputStream bis = new BufferedInputStream(fis);
// Write bytes
int b;
byte[] d = new byte[8];
while((b = bis.read(d)) != -1) {
bos.write(d, 0, b);
}
// Flush and close streams.
bos.flush();
bos.close();
bis.close();
}
public static void decryptAndClose(FileInputStream fis, FileOutputStream fos)
throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
SecretKeySpec sks = new SecretKeySpec("1234567890123456".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
//wrap input with buffer stream
BufferedInputStream bis = new BufferedInputStream(cis);
//wrap output with buffer stream
BufferedOutputStream bos = new BufferedOutputStream(fos);
int b;
byte[] d = new byte[8];
while((b = bis.read(d)) != -1) {
bos.write(d, 0, b);
}
bos.flush();
bos.close();
bis.close();
}
static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
if (fileToZip.isHidden()) {
return;
}
if (fileToZip.isDirectory()) {
if (fileName.endsWith("/")) {
zipOut.putNextEntry(new ZipEntry(fileName));
zipOut.closeEntry();
} else {
zipOut.putNextEntry(new ZipEntry(fileName + "/"));
zipOut.closeEntry();
}
File[] children = fileToZip.listFiles();
for (File childFile : children) {
zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
}
return;
}
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileName);
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
fis.close();
}
static void unZipFile(ZipEntry zipEntry,File destDir,ZipInputStream zis, byte[] buffer) throws IOException{
while (zipEntry != null) {
File newFile = newFile(destDir, zipEntry);
if (zipEntry.isDirectory()) {
if (!newFile.isDirectory() && !newFile.mkdirs()) {
throw new IOException("Failed to create directory " + newFile);
}
} else {
// fix for Windows-created archives
File parent = newFile.getParentFile();
if (!parent.isDirectory() && !parent.mkdirs()) {
throw new IOException("Failed to create directory " + parent);
}
// write file content
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
}
zipEntry = zis.getNextEntry();
}
}
public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
File destFile = new File(destinationDir, zipEntry.getName());
String destDirPath = destinationDir.getCanonicalPath();
String destFilePath = destFile.getCanonicalPath();
if (!destFilePath.startsWith(destDirPath + File.separator)) {
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
}
return destFile;
}
public static void main(String[]args) {
//compress to zip.
String sourceFile = "C:\\test";
FileOutputStream fos;
try {
fos = new FileOutputStream("C:\\test\\test.zip");
ZipOutputStream zipOut = new ZipOutputStream(fos);
File fileToZip = new File(sourceFile);
zipFile(fileToZip, fileToZip.getName(), zipOut);
zipOut.close();
fos.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//encrypt the zip.
String outDir = "C:/test";
String outFilename = "test-encrypt.zip";
String inDir = "C:/test";
String inFilename = "test.zip";
File output= new File(outDir, outFilename);
File input= new File(inDir, inFilename);
if (input.exists()) {
System.out.println("test");
FileInputStream inStream;
try {
inStream = new FileInputStream(input);
FileOutputStream outStream = new FileOutputStream(output);
encryptAndClose(inStream, outStream);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
代码的目的是创建一个zip文件,然后用AES加密生成的zip文件。代码可以成功地生成一个可以用WinZip或7zip压缩和解压缩的zip文件。
但是,当它试图加密生成的zip文件时,代码反而会导致文件(例如the crypt.zip)被破坏,并且不能被WinZip或7zip之类的程序打开。
如果可能的话,我希望在不使用zip4j的情况下这样做。我的代码和对代码的理解有什么问题吗?
这是我第一次使用加密技术,任何帮助都将不胜感激!
发布于 2022-09-07 14:49:23
如果首先创建ZIP,然后使用AES算法或其他算法加密ZIP文件,则输出文件将不再是ZIP。它不会遵循ZIP标准格式。所以,解压缩是不可能的。
您需要首先解密文件并取回原始的ZIP,然后才能使用任何知名的zip处理软件打开/解压缩原始zip。
加密ZIP文件会导致文件内的字节发生变化,导致软件无法识别文件头、必要的ZipEntry记录结构等。
最好的选择是在创建zip时提供一个密码,这样如果没有密码就不能解压缩。或加密原始文件,然后将加密的文件放入Zip中。但是,不要加密ZIP文件。
发布于 2022-10-06 16:38:44
Java不支持压缩文件加密。无论如何,它支持非常有限的活动与zip文件。您必须设法使您使用zip文件要容易得多。你可以检查zip4jvm
创建(或打开现有的)压缩存档,并使用AES 256位加密添加一些常规文件和/或目录。
Path zip = Paths.get("filename.zip");
Collection<Path> paths = Arrays.asList(
Paths.get("/bikes/ducati-panigale-1199.jpg"),
Paths.get("/bikes/honda-cbr600rr.jpg"),
Paths.get("/cars"),
Paths.get("/saint-petersburg.jpg"));
ZipEntrySettings settings = ZipEntrySettings.builder()
.encryption(Encryption.AES_256, "password".toCharArray())
.build();
ZipIt.zip(zip).entrySettings(settings).add(paths);
要获得更多关于zip中AES加密的详细信息,可以查看AesEncoder.java
https://stackoverflow.com/questions/73637361
复制相似问题