使用 Apache POI 进行二进制文件加密

如何解决使用 Apache POI 进行二进制文件加密

我正在尝试使用 Apache POI 对二进制 xls 文件应用加密。 虽然我可以成功加密基于 xml 的文件,但如果我加密一个二进制文件,我将无法打开它,并且会收到错误的密码错误

这是我的代码

@Test
public void testEncryption() throws Exception {

    File file = new File("file.xls");

    Workbook workbook = new hssfWorkbook();
    setData(workbook);
    FileOutputStream fileOutputStream = new FileOutputStream(file);
    workbook.write(fileOutputStream);
    fileOutputStream.close();

    encryptFile(file,"pass");
}

public void encryptFile(File file,String encryptKey) throws Exception {

    FileInputStream fileInput = new FileInputStream(file.getPath());
    BufferedInputStream bufferInput = new BufferedInputStream(fileInput);
    POIFSFileSystem poiFileSystem = new POIFSFileSystem(bufferInput);
    Biff8EncryptionKey.setCurrentUserPassword(encryptKey);

    hssfWorkbook workbook = new hssfWorkbook(poiFileSystem,true);
    FileOutputStream fileOut = new FileOutputStream(file.getPath());
    workbook.writeProtectWorkbook(Biff8EncryptionKey.getCurrentUserPassword(),"");
    workbook.write(fileOut);
    bufferInput.close();
    fileOut.close();

    Biff8EncryptionKey.setCurrentUserPassword(null);
}

解决方法

要加密 HSSF,您只需在写入 Biff8EncryptionKey.setCurrentUserPassword 之前执行 HSSFWorkbook

最简单的例子如下:

import java.io.FileOutputStream;

import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;

public class EncryptHSSF {
    
 static void setData(HSSFWorkbook workbook) {
   Sheet sheet = workbook.createSheet();
   Row row = sheet.createRow(0);
   Cell cell = row.createCell(0);
   cell.setCellValue("Test");
 }

 public static void main(String[] args) throws Exception {
  try (HSSFWorkbook workbook = new HSSFWorkbook();
       FileOutputStream out = new FileOutputStream("file.xls") ) {
    
   setData(workbook);       

   Biff8EncryptionKey.setCurrentUserPassword("pass");
   workbook.write(out);
   
  }
 }
}

这对我有用。如果我使用 file.xls 打开 Excel,它会要求我输入密码,如果我在那里输入 pass,工作簿会打开。

如果目的是加密现有的未加密工作簿,则如下所示:

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class EncryptHSSFExistingFile {
    
 public static void main(String[] args) throws Exception {
  try (HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream("Unencrypted.xls"));
       FileOutputStream out = new FileOutputStream("Encrypted.xls") ) {
    
   Biff8EncryptionKey.setCurrentUserPassword("pass");
   workbook.write(out);
   
  }
 }
}

同样的解决方案。只需在编写 Biff8EncryptionKey.setCurrentUserPassword 之前执行 HSSFWorkbook

此代码仅创建用于 Microsoft Excel 的正确加密工作簿。 LibreOffice Calc 无法打开这些文件。因此,LibreOffice Calc 使用的加密方法似乎未知。但我还没有找到改变 HSSF 加密方法的方法。因此,HSSF 中似乎没有完全提供 apache poi 加密。 Apache POI - Encryption support 也没有显示示例。因此,您可以打开和重写加密的 HSSFWorkbook。如果 Biff8EncryptionKey.setCurrentUserPassword 未设置 null,则新写入的工作簿也会被加密。但是您不能从头开始编写加密的 HSSFWorkbook

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?