如何使用 Java 以编程方式签署二进制 MS Office 文档?

2024-02-27

我们如何在 Apache POI 或任何其他开源库中对旧版二进制 MS-Office 文档(doc、xls、ppt)进行数字签名?

Open XML 格式包含在如何使用 Java 以编程方式签署 MS Office XML 文档? https://stackoverflow.com/questions/22522187/how-to-programatically-sign-an-ms-office-xml-document-with-java


我能够通过创建分离的 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();
        }

    }


}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Java 以编程方式签署二进制 MS Office 文档? 的相关文章

随机推荐

  • Highcharts,使 y 轴从零开始

    我想这对某些人来说应该是理所当然的 但我在那些可怕的自动生成的文档中找不到它 您应该在图表对象中添加 yAxis 属性min 0这是一个类似的问题 如何设置 Highcharts 图表最大 y 轴值 https stackoverflow
  • 让Git在分支之间保留不同的section内容

    我正在开发一个用户脚本 我的雇主要求我开始通过 Git 进行管理 现在 我有一个稳定文件和一个测试版文件 以便组织中的每个人都可以安装稳定代码 但如果愿意 可以选择帮助测试测试版添加内容 该文件的某些部分应保持不同 内容和更改不应在分支之间
  • 使用 pandoc ruby​​ 将 HTML 和内联 Mathjax 数学转换为 LaTeX

    我正在构建一个Rails应用程序 并且正在寻找一种方法将带有html和内联MathJax数学 TeX 的数据库条目转换为LaTeX以创建pdf 我发现了和我类似的问题 使用 pandoc 将 html mathjax 转换为 Markdow
  • 这个==- JavaScript 运算符是什么?

    当我发现时 我跌跌撞撞地尝试不同的条件 or 在 JS 控制台中 您可以编写 var a 那么以下是正确的 a 但这是错误的 a 然而 如果你说 a or a 那么这是什么俏皮的东西 操作员 他们不是不同的运营商 Writing a 被解析
  • 使用 XAMPP 包在本地显示 php 站点时出现问题。站点在远程服务器上运行良好

    我在 stackoverflow com 上发表的第一篇文章 一个很棒的网站 我希望我的帖子能为他人的利益做出贡献 情况 我受委托翻新一处really小型 现有 php 驱动的网站 于是 我开始搭建我的环境 Dreamweaver 已安装
  • Selenium 使用 Firefox 配置文件

    我尝试在 Windows 10 系统上使用 Selenium Webdriver 和 Python 来实现浏览器操作的一些自动化 但我有这个问题 Selenium 启动的 Firefox 窗口没有 看到 我已经登录 并且目标站点将我发送到登
  • R 闪亮销毁观察事件

    我是 R Shiny 的新手 我正在尝试创建一个带有一些动态生成的按钮的应用程序 每个按钮都有一个与之关联的observeEvent 我想添加一个重置按钮来删除所有observeEvents 我浏览了一些链接 发现 destroy 函数可以
  • ASP.NET MVC3 中的 HtmlHelper 使用 Action 作为模板:Razor 语法?

    首先我要说的是 也许有更好的方法可以做到这一点 而 Razor 正在为我们指明道路 无论如何 我有一个 HTML 帮助器 它充当某种重复器 但在任意次数的重复之后 它会插入一个备用模板 最明显的用途 在 x 个单元格之后开始新行的表格 助手
  • HTML、jQuery:将一个元素的宽度绑定到另一个元素

    我想将第一个元素 foo 的宽度绑定到第二个元素 bar 的宽度 我希望当元素 bar 的宽度更改时 元素 foo 的宽度自动更改 我知道我可以将元素 foo 的宽度设置为元素 bar 的宽度 正如我们在下面的代码中看到的那样 但这是一次性
  • Visual Basic 2008 中的集合初始化语法?

    我试图确定 Visual Basic 2008 如果重要的话 是 Express 版本 中是否有一种方法可以像 JavaScript 或 Python 那样进行内联集合初始化 Dim oMapping As Dictionary Of In
  • 检测和存储 Web 应用程序客户端所在时区的最佳方法是什么?

    我有一个多时区 Web 应用程序 它将所有 UTC 日期时间值存储在数据库中 当服务器上发生操作时 我可以轻松地将时间转换为 UTC 但是 当客户端输入时间或时间跨度时 检测和存储它的最佳方法是什么 我目前正在做以下事情 获取 Date g
  • 程序执行期间Apache-Spark出现超时异常

    我正在 MAC 中运行 Bash 脚本 该脚本多次调用用Scala语言编写的spark方法 我目前正在尝试使用 for 循环调用此 Spark 方法 100 000 次 在运行少量迭代 大约 3000 次迭代 后 代码退出并出现以下异常 o
  • 在 Jenkins 上构建多项目 Gradle

    我有一个在 Mercurial 存储库中托管的 Gradle 多项目 我想以这样的方式设置我的 Jenkins 如果我只将更改提交到 1 个子项目 那么只有该子项目将被构建并发布到我的 Nexus 存储库 有人可以给我提示吗 或者说这完全有
  • Spring MVC(或 Spring Boot)。针对安全相关异常的自定义 JSON 响应,例如 401 Unauthorized 或 403 Forbidden)

    我正在开发 REST 服务 它使用 JSON 并且必须返回一些预定义的 JSON 对象 以防出现问题 默认的 Spring 响应如下所示 timestamp 1512578593776 status 403 error Forbidden
  • 如何从java实例化在scala中定义的嵌套泛型类?

    我试图从 Java 实例化一个嵌套通用 Scala 类并遇到此编译错误 有人可以帮忙吗 谢谢 外部 scala class Outer class Inner A sctest java public class sctest public
  • HTML 标签表到文本字段 - JasperReport

    我有一个使用 html 标记语言或样式的参数输入到文本字段 但是当我放置标签时 它根本不显示 Jaspersoft 支持的 thid 标签 b b u u i i font font
  • 如何结合对称加密和非对称加密?

    在谈论非对称加密时 人们经常说 由于某些原因 您不应该对整个消息进行非对称加密 例如性能考虑 通常建议的工作流程是 创建对称加密的随机密钥 使用此随机密钥加密消息 使用非对称加密对随机密钥进行加密 将加密消息和加密密钥发送给接收者 到目前为
  • Azure 逻辑应用 - 用于部署文件系统 API 连接的 ARM 模板

    我正在尝试使用 ARM 模板部署文件系统 API 连接 我找不到此连接的parametersValue架构 因此尝试按照Azure门户上显示的参数命名它们 在 Azure 门户上编辑 API 连接屏幕截图1 https i stack im
  • 用自己的实现和信任管理器替换 SSLContext 默认值

    基于 Jcs 的回答 HttpUnit WebConversation SSL 问题 https stackoverflow com questions 4868654 httpunit webconversation ssl issues
  • 如何使用 Java 以编程方式签署二进制 MS Office 文档?

    我们如何在 Apache POI 或任何其他开源库中对旧版二进制 MS Office 文档 doc xls ppt 进行数字签名 Open XML 格式包含在如何使用 Java 以编程方式签署 MS Office XML 文档 https