All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ofdrw.crypto.integrity.OFDIntegrity Maven / Gradle / Ivy

Go to download

依照《GM/T 0099-2020 开放板式文档密码应用技术规范》实现OFD加解密、完整性保护等密码操作。

The newest version!
package org.ofdrw.crypto.integrity;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.jetbrains.annotations.NotNull;
import org.ofdrw.core.basicType.ST_Loc;
import org.ofdrw.core.integrity.FileList;
import org.ofdrw.core.integrity.OFDEntries;
import org.ofdrw.gv.GlobalVar;
import org.ofdrw.pkg.container.OFDDir;
import org.ofdrw.pkg.tool.ElemCup;
import org.ofdrw.reader.ZipUtil;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.GeneralSecurityException;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * OFD完整性保护协议实现
 *
 * @author 权观宇
 * @since 2021-08-17 19:41:53
 */
public class OFDIntegrity implements Closeable {
    /**
     * OFD虚拟容器根目录
     */
    private OFDDir ofdDir;

    /**
     * 加密后文件输出位置
     */
    private Path dest;

    /**
     * 工作过程中的工作目录
     * 

* 用于存放解压后的OFD文档容器内容 */ private Path workDir; private boolean closed; private AtomicInteger idProvider; public OFDIntegrity(@NotNull Path ofdFile, @NotNull Path dest) throws IOException { if (ofdFile == null || Files.notExists(ofdFile)) { throw new IllegalArgumentException("待保护文件位置(ofdFile)不正确"); } if (dest == null) { throw new IllegalArgumentException("完整性保护文件输出位置(out)为空"); } idProvider = new AtomicInteger(0); this.dest = dest; this.workDir = Files.createTempDirectory("ofd-tmp-"); // 解压文档,到临时的工作目录 ZipUtil.unZipFiles(ofdFile.toFile(), this.workDir.toAbsolutePath() + File.separator); this.ofdDir = new OFDDir(workDir.toAbsolutePath()); } /** * 对文件实行完整性保护 *

* 请在完成保护后务必调用{@link #close()} 以清除工作过程中的临时文件! * * @param signer 签名实现 * @throws IOException IO操作异常 * @throws GeneralSecurityException 密码运算相关问题 */ public void protect(@NotNull ProtectSigner signer) throws IOException, GeneralSecurityException { if (signer == null) { throw new IllegalArgumentException("请提供 签名实现"); } final FileList fileList = new FileList(); final OFDEntries ofdEntries = new OFDEntries() .setID(String.valueOf(this.idProvider.incrementAndGet())) .setCreatorName("ofdrw-crypto") .setVersion(GlobalVar.Version) .setCreationDate(LocalDateTime.now()); ofdEntries.setSignedValueLoc(ST_Loc.getInstance("/signedvalue.dat")) .setFileList(fileList); Path ofdEntriesPath = this.workDir.resolve("OFDEntries.xml"); Path signedValuePath = this.workDir.resolve("signedvalue.dat"); // a) 确认文件包内的所有文件 // 文件系统中的容器Unix类型绝对路径,如:"/home/root/tmp" String sysRoot = FilenameUtils.separatorsToUnix(this.workDir.toAbsolutePath().toString()); Files.walkFileTree(this.workDir, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { // 路径转换为Unix类型的绝对路径 String abxFilePath = FilenameUtils.separatorsToUnix(file.toAbsolutePath().toString()); // 替换文件系统的根路径,这样就为容器系统中的绝对路径 abxFilePath = abxFilePath.replace(sysRoot, ""); String id = String.valueOf(idProvider.incrementAndGet()); // b) 组装 签名完整性保护文件 fileList.addFile(id, abxFilePath); return FileVisitResult.CONTINUE; } }); // 把清单写入文件 ElemCup.dump(ofdEntries, ofdEntriesPath); // c) 根据签名方案,计算完整性保护文件的杂凑值; // d) 根据签名方案,使用版式文件合成者的签名私钥对杂凑值进行数字签名; // 执行签名 final byte[] signature = signer.digestThenSign(ofdEntriesPath); // e) 将数字签名结果写入签名值文件 // 把签名值写入文件 Files.write(signedValuePath, signature); // 执行打包程序 this.ofdDir.jar(dest); } /** * 请务必在程序结束时调用该方法释放 *

* 工作过程中产生的临时文件 * * @throws IOException 文件删除IO异常 */ @Override public void close() throws IOException { if (closed) { return; } closed = true; if (workDir != null && Files.exists(workDir)) { try { FileUtils.deleteDirectory(workDir.toFile()); } catch (IOException e) { throw new IOException("无法删除Reader的工作空间,原因:" + e.getMessage(), e); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy