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

时间:2018-02-05 05:41:16

标签: java excel apache-poi digital-signature mscapi

我使用以下代码生成数字签名并将其添加到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

1 个答案:

答案 0 :(得分:0)

我现在通过#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);
        }
    }
}