如何将数字签名添加到 Excel 和 JPG 文件



我使用以下代码生成数字签名并将其添加到Excel文件中:

            SignedObject signedHashObject =null;
            signatureConfig.setKey((PrivateKey) privateKey);signatureConfig.setSigningCertificateChain(Collections.singletonList(Util.getX509Certificate(certificateAlias)));
            OPCPackage pkg = OPCPackage.open(selectedFileName, PackageAccess.READ_WRITE);
            signatureConfig.setOpcPackage(pkg);
            SignatureInfo si = new SignatureInfo();
            si.setSignatureConfig(signatureConfig);
            si.confirmSignature();
            pkg.close();

这里的私钥是java.security.mscapi.rsaprivatekey。

修复所有版本兼容性问题后,我遇到了以下错误,

类型为 sun.security.mscapi.RSAPrivateKey 的指定密钥不是 RSAPrivateKey

我现在已通过#62159解决此问题。

确保在 JVM 属性中设置-Dorg.apache.xml.security.ignoreLineBreaks=true

完整的示例,即我的测试代码:

import java.awt.geom.Rectangle2D;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.poifs.crypt.dsig.SignatureConfig;
import org.apache.poi.poifs.crypt.dsig.SignatureInfo;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFTextBox;
public class CertTest {
    static PrivateKey winKey;
    static List<X509Certificate> winChain;
    public static void main(String[] args) throws Exception {
        System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
        HashAlgorithm hashes[] = { HashAlgorithm.sha1, HashAlgorithm.sha256, HashAlgorithm.sha384, HashAlgorithm.sha512 };
        loadWinKey();
        SignatureConfig signatureConfig = new SignatureConfig();
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(2018, 1, 18, 12, 0, 0);
        signatureConfig.setExecutionTime(cal.getTime());
        for (final HashAlgorithm ha : hashes) {
            try (final OPCPackage pkg = loadOPC("test-" + ha + ".pptx")) {
                signatureConfig.setDigestAlgo(ha);
                signatureConfig.setKey(winKey);
                signatureConfig.setSigningCertificateChain(winChain);
                signatureConfig.setOpcPackage(pkg);
                SignatureInfo si = new SignatureInfo();
                si.setSignatureConfig(signatureConfig);
                si.confirmSignature();
            }
        }
    }
    static void loadWinKey() throws Exception {
        String alias = "poitest";
        KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
        keystore.load(null, null);
        winKey = (PrivateKey) keystore.getKey(alias, null);
        winChain = Collections.singletonList((X509Certificate) keystore.getCertificate(alias));
    }
    static OPCPackage loadOPC(String fileName) throws Exception {
        try (final XMLSlideShow ppt = new XMLSlideShow()) {
            try (final FileOutputStream fos = new FileOutputStream(fileName)) {
                XSLFTextBox tb = ppt.createSlide().createTextBox();
                tb.setText("test");
                tb.setAnchor(new Rectangle2D.Double(100, 100, 100, 100));
                ppt.write(fos);
            }
            return OPCPackage.open(fileName, PackageAccess.READ_WRITE);
        }
    }
}

最新更新