如何使用Java以编程方式对二进制MS office文档进行签名?

如何使用Java以编程方式对二进制MS office文档进行签名?,java,ms-office,xls,doc,Java,Ms Office,Xls,Doc,我们如何在ApachePOI或任何其他开源库中对遗留的二进制MS Office文档(doc、xls、ppt)进行数字签名 打开的XML格式将在中介绍,我可以通过创建分离的XML签名来对.doc文件进行签名,然后使用POIFSFileSystem将其添加到根目录下,示例如下: public class OfficeDocumentSigner2 { public static void main(String[] args) { signClassicOfficeDoc

我们如何在ApachePOI或任何其他开源库中对遗留的二进制MS Office文档(doc、xls、ppt)进行数字签名


打开的XML格式将在

中介绍,我可以通过创建分离的XML签名来对.doc文件进行签名,然后使用POIFSFileSystem将其添加到根目录下,示例如下:

public class OfficeDocumentSigner2 {


    public static void main(String[] args) {
        signClassicOfficeDocuments();
    }

    private static String sign() {

        // First, create a DOM XMLSignatureFactory that will be used to
        // generate the XMLSignature and marshal it to DOM.
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
        OutputStream os = null;
        String signedDoc = "C:\\Users\\Desktop\\digitalSign\\signdoc_signed.xml";
        try {
            // Create a Reference to an external URI that will be digested
            // using the SHA1 digest algorithm

            Reference ref = fac.newReference(officeFilePath, fac.newDigestMethod(DigestMethod.SHA1, null));
            // Create the SignedInfo
            SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, (C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                    Collections.singletonList(ref));

            // Create the Document that will hold the resulting XMLSignature --> detached
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true); // must be set
            Document doc = dbf.newDocumentBuilder().newDocument();

            // certificate info
            File file = new File("C:\\Users\\Desktop\\digitalSign\\test101\\KeyStore.jks");
            // extracting private key and certificate
            String alias = "certAlias";
            X509Certificate x509 = null;
            // loading the keystore
            KeyStore keystore = KeyStore.getInstance("JKS");
            FileInputStream fis = new FileInputStream(file);
            keystore.load(fis, password);
            fis.close();
            x509 = (X509Certificate) keystore.getCertificate(alias);
            KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) keystore.getEntry(alias, new KeyStore.PasswordProtection(password));

            // Create the KeyInfo containing the X509Data.
            // ref : http://www.oracle.com/technetwork/articles/javase/dig-signature-api-140772.html
            KeyInfoFactory kif = fac.getKeyInfoFactory();
            List x509Content = new ArrayList();
            x509Content.add(x509.getSubjectX500Principal().getName());
            x509Content.add(x509);
            X509Data xd = kif.newX509Data(x509Content);
            KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

            // Create a DOMSignContext and specify the DSA PrivateKey and
            // location of the resulting XMLSignature's parent element
            DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc);
            dsc.setBaseURI(baseURI);
            // Create the XMLSignature (but don't sign it yet)
            XMLSignature signature = fac.newXMLSignature(si, ki);

            // Marshal, generate (and sign) the enveloped signature
            signature.sign(dsc);

            // Output the resulting document.

            os = new FileOutputStream(signedDoc);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer trans = tf.newTransformer();
            trans.transform(new DOMSource(doc), new StreamResult(os));


        } catch (Exception e) {
            e.printStackTrace();
        }
        return signedDoc;
    }

    public static void signClassicOfficeDocuments() {

        InputStream is;
        try {
            //sign document
            String signaturePath = sign();
            InputStream signatureAsIS = new FileInputStream(signaturePath);

            is = new FileInputStream(fileName);
            POIFSFileSystem poifs = new POIFSFileSystem(is);
            DirectoryEntry dirEntry =  poifs.createDirectory("_xmlsignatures"); // create a new DirectoryEntry in the root directory
            dirEntry.createDocument("9149", signatureAsIS);

            String destPath = "C://Users//Desktop//digitalSign//test_11_24_signedByMe.doc";
            OutputStream os = new FileOutputStream(destPath);
            poifs.writeFilesystem(os);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}

由于缺乏研究工作而被否决:您是否尝试过在您选择的搜索引擎中搜索“ApachePOI数字签名”?我想到了很多例子,例如,我看过这些例子并尝试过,但它们只适用于.docx、.pptx类型的文件。xlsx(基于xml的文件)。我应该在这里放什么<代码>officeFilePath第行
参考参考=fac.newReference(officeFilePath,fac.newDigestMethod(DigestMethod.SHA1,null))文档文件的路径,例如:D:\document.docx