Java使用poi为excel设置allow edit ranges密码,生成的excel提示密码错误

Java uses poi to set the allow edit ranges password for excel, and the generated excel prompts that the password is incorrect

我正在使用 java 设置 Excel ‘allow edit ranges’ 密码, allow edit ranges

下面是我的核心代码

    String pwd = "AB";
    byte[] decode = Hex.decodeHex(pwd.toCharArray());
    CTProtectedRange ctProtectedRange = sheet.getCTWorksheet().addNewProtectedRanges().addNewProtectedRange();
    ctProtectedRange.setName("protect");
    ctProtectedRange.setPassword(decode);
    System.out.println(ctProtectedRange); //get this string:<xml-fragment name="protect" password="AB"/>
    ctProtectedRange.setSqref(List.of("A1:D1"));
    sheet.protectSheet("1");

当我从浏览器下载excel时,我点击受保护的单元格并输入密码:'AB',但我收到密码错误的提示

我能得到什么建议吗?

CTProtectedRange.setPassword 中使用的 byte[]2.3.7.1 Binary Document Password Verifier Derivation Method 1 中描述的 16 位密码验证器的字节。

这可以使用 CryptoFunctions.createXorVerifier1 创建。请注意,由于 ist 仅为 16 位,这实际上 returns 仅 short 范围内的 int

然后可以使用 java.nio.ByteBuffer 创建 byte[]

示例:

...
  String pwd = "AB";
  short pwdHash = (short)org.apache.poi.poifs.crypt.CryptoFunctions.createXorVerifier1(pwd);
  byte[] pwdHashBytes = java.nio.ByteBuffer.allocate(2).putShort(pwdHash).array();
  ctProtectedRange.setPassword(pwdHashBytes);
...

这只是一种混淆方法,由于只有 65,536 个不同的密码哈希值,因此它在抵御暴力攻击时不是很安全。这是唯一使用 Excel 2007 的方法。后来的 Excel 版本提供了使用散列值和盐的散列算法的方法。那样比较安全

使用散列算法 SHA-512 为保护范围设置密码,散列值和盐可能如下所示:

...
  String pwd = "AB";
  org.apache.poi.poifs.crypt.HashAlgorithm hashAlgorithm = org.apache.poi.poifs.crypt.HashAlgorithm.sha512;
  byte[] saltValue = new byte[]{123, 64, 89, 23, -123, -34, 89, -3};
  int spinCount = 10000;
  byte[] hashValue = org.apache.poi.poifs.crypt.CryptoFunctions.hashPassword(pwd, hashAlgorithm, saltValue, spinCount, false);
  ctProtectedRange.setAlgorithmName(hashAlgorithm.jceId);
  ctProtectedRange.setSaltValue(saltValue);
  ctProtectedRange.setHashValue(hashValue);
  ctProtectedRange.setSpinCount(spinCount);
...