iText 通过检查 CRL 来验证签名

2023-12-22

我正在设置一个验证器,可以检查签名的有效性。

我所做的签名基于 DSS 级别 LT,因此文档中内置了撤销检查。

我现在遇到的问题是在我在iText中开发的验证器层面。它允许验证签名的有效性以及撤销信息的有效性。根据我的研究,IText 允许基于 pkcs7.getCrl() 验证签名本身中的此信息。

然而,DSS 签名将撤销信息合并到字典中。

下面是我用来验证签名的代码:

import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.security.PdfPKCS7;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class TestCheck {

    public static String pdf_file = "CURRENT_SIGNATURE.pdf";

    public static final boolean verifySignature(PdfReader pdfReader)
            throws GeneralSecurityException, IOException {
        
        boolean valid = false;
        AcroFields acroFields = pdfReader.getAcroFields();
        
        
        PdfDictionary sigDict = acroFields.getSignatureDictionary("Signature1"); 
        System.out.println(sigDict);
        PdfString contents = sigDict.getAsString(PdfName.CONTENTS);

        
        List<String> signatureNames = acroFields.getSignatureNames();
        if (!signatureNames.isEmpty()) {
            for (String name : signatureNames) {
//                if (acroFields.signatureCoversWholeDocument(name)) {
                    PdfPKCS7 pkcs7 = acroFields.verifySignature(name);
                    valid = pkcs7.verify();
                    String reason = pkcs7.getReason();
                    Calendar signedAt = pkcs7.getSignDate();
                    X509Certificate signingCertificate = pkcs7.getSigningCertificate();
                    Principal issuerDN = signingCertificate.getIssuerDN();
                    Principal subjectDN = signingCertificate.getSubjectDN();
                    System.out.println("valid = "+valid);
                    //System.out.println("date = "+signedAt.getTime());
                    ////System.out.println("reason = "+reason);
                    //System.out.println("issuer = "+issuerDN);
                    //System.out.println("subject = "+subjectDN);
                    System.out.println("CRL : " + pkcs7.getCRLs());
                    break;
                }
           // }
        }
        return valid;
    }

    public static void main(String[] args) throws Exception {

        BouncyCastleProvider provider = new BouncyCastleProvider();
        Security.addProvider(provider);
        
        InputStream is = new FileInputStream(new File(pdf_file));
        PdfReader reader = new PdfReader(is);
        
        
        boolean ok = verifySignature(reader);
        System.out.println("Ver : "+ ok);
    }
}

最初我想简单地指出LtvVerifieriText 5 和 iText 7 均提供的类。不过,使用该类进行测试后发现,它不适用于当前的 PAdES BASELINE 配置文件,而是专为较旧的 PAdES-LTV 配置文件而设计(请参阅 ETSI TS 102 778-4第 4 节“PAdES-LTV 简介”)。

不过,如果我正确理解您的问题,您已经知道如何评估 CRL 和 OCSP 响应。因此,如果您了解如何从 DSS 字典中提取吊销信息就足够了。

您的示例代码显然使用 iText 5.x,因此我使用当前的 iText 5.5.14-SNAPSHOT。稍旧的版本也应该可以使用相同的代码。

PdfReader pdfReader = new PdfReader(...);

PdfDictionary dss = pdfReader.getCatalog().getAsDict(PdfName.DSS);
if (dss == null)
    System.out.println("No DSS in PDF");
else {
    PdfArray crlarray = dss.getAsArray(PdfName.CRLS);
    if (crlarray == null || crlarray.size() == 0)
        System.out.println("No CRLs in DSS");
    else {
        System.out.println("CRLs:");
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        for (int i = 0; i < crlarray.size(); i++) {
            PRStream stream = (PRStream) crlarray.getAsStream(i);
            X509CRL crl = (X509CRL)cf.generateCRL(new ByteArrayInputStream(PdfReader.getStreamBytes(stream)));

            System.out.printf("  '%s' update %s\n", crl.getIssuerX500Principal(), crl.getThisUpdate());
        }
    }

    PdfArray ocsparray = dss.getAsArray(PdfName.OCSPS);
    if (ocsparray == null || ocsparray.size() == 0)
        System.out.println("\nNo OCSP responses in DSS");
    else {
        System.out.println("\nOCSP Responses:");
        for (int i = 0; i < ocsparray.size(); i++) {
            PRStream stream = (PRStream) ocsparray.getAsStream(i);
            OCSPResp ocspResponse = new OCSPResp(PdfReader.getStreamBytes(stream));
            if (ocspResponse.getStatus() == 0) {
                try {
                    BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResponse.getResponseObject();
                    System.out.printf("  '%s' update %s\n", basicOCSPResp.getResponderId(), basicOCSPResp.getProducedAt());
                } catch (OCSPException e) {
                    throw new GeneralSecurityException(e);
                }
            }
        }
    }
}

(验证Ltv https://github.com/mkl-public/testarea-itext5/blob/master/src/test/java/mkl/testarea/itext5/signature/VerifyLtv.java#L104 test testExtractRevocationInformationCURRENT_SIGNATURE)

而不是将信息打印到System.out您当然可以收集 CRL 和 OCSP 响应并像以前一样处理它们。

此外,您当然可以检查从PdfPKCS7对象和来自 DSS 的数据。 Adobe Acrobat 在验证过程中也同时使用这两者。

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

iText 通过检查 CRL 来验证签名 的相关文章

  • 将 WAR 部署到 Tomcat(Spring Boot + Angular)

    我正在尝试使用以下命令部署 Spring Boot 应用程序WAR包装至Tomcat 10 应用程序已成功部署 但是 当我尝试访问端点时 它会导致404 未找到 战争文件 应用程序 war http localhost 8080 appli
  • 使用itext java库复制时pdf文件大小大大增加

    我正在尝试使用 Java 中的 itextpdf 库将现有的 pdf 文件复制到一些新文件中 我使用的是 itextpdf 5 5 10 版本 我在两种方式上都面临着不同的问题 PDFStamper 和 PdfCopy 当我使用 PDFSt
  • 二元运算符 >=、-、* 的错误操作数类型

    我无法弄清楚如何修复代码中不断出现的这些错误 import java util Scanner public class Unit02Prog1 public static void main String args Scanner inp
  • 使用 Spring MVC 在 jar 文件中显示 jsp 页面

    我正在使用 Spring MVC 3 2 2 在 java 中开发一个 Web 应用程序 我在从 jar 文件中加载 jsp 页面时遇到问题 Spring MVC Web应用程序具有以下结构 META INF WEB INF spring
  • 如何杀死 Java Future?

    我正在开发的服务使用 Future 来并行运行多个任务 每个任务最多可能需要一分钟才能完成 然而 外部库似乎有问题 因为在某些情况下 2 的时间 它不会返回 在这些情况下 我想给出 2 分钟的等待时间 如果还没有返回 我想杀死 future
  • 用于制作代码编辑器的 JavaFX 相当于 JSyntaxPane 的什么?

    以前在 Swing 中 我使用过JSyntaxPane用于制作一个小型 Java 源代码编辑器 为了练习 我决定用 JavaFX 重做整个项目并添加对更多语言的支持 最好是尽可能多 不过好像没有什么类似的JSyntaxPane 一些研究让我
  • 如何在正则表达式中编写可选单词?

    我想编写一个识别以下模式的 java 正则表达式 abc def the ghi and abc def ghi 我试过这个 abc def the ghi 但是 它没有识别第二种模式 我哪里出错了 abc def the ghi 删除多余
  • 如何使用 aether 从 Java 找到最新版本的 Maven 工件?

    他们的文档非常薄弱 我无法弄清楚 我找到了部分答案here https stackoverflow com questions 27428068 how to retrieve the latest also snapshot versio
  • 递归取消 allOf CompletableFuture

    如果我有 CompletableFuture
  • 是否可以创建 Java RAM 磁盘以与 java.io.* API 一起使用?

    我正在使用一个第三方库 它基本上创建一个输出目录 其中包含不同类型的文件和子目录 我希望能够编写单元测试来确认输出正确 我希望能够将库与 RAM 磁盘一起使用 这样库所做的任何事情都不会以任何方式接触实际的磁盘板 这个想法是让测试运行和清理
  • 在 Eclipse 中删除空块之前的新行

    我更喜欢奥尔曼式 http en wikipedia org wiki Brace style Allman style大括号 例如 if foo magical prancing unicorn stuff 而不是 if foo unma
  • 生成一定长度的所有排列

    假设我们有一个字母表 abcdefghiklimnop 如何以有效的方式以五个一组的形式重复该字母表来递归生成排列 几天来我一直在为此苦苦挣扎 任何反馈都会有帮助 本质上这与 生成给定字符串的所有排列 https stackoverflow
  • Spring Security 角色层次结构不适用于 Thymeleaf sec:authorize

    我正在使用 Spring Security 3 2 5 RELEASE 和 ThymeLeaf 2 1 4 RELEASE 我已经在安全上下文中定义了角色层次结构 在我的视图层中我正在使用sec authorize属性来定义菜单项 我希望看
  • 在 Kotlin 中声明静态属性?

    My Java code public class Common public static ModelPengguna currentModelPengguna public class Common companion object v
  • 如何使用 AffineTransform.quadrantRotate 旋转位图?

    我想旋转一个bitmap关于它的中心点 然后将其绘制成更大的图形上下文 位图是40x40 pixels 图形上下文是500x500 pixels 这就是我正在做的 BufferedImage bi new BufferedImage 500
  • 为什么/何时应该使用泛型方法?

    学习Java的时候遇到过通用方法 public
  • 用于生成 ISO 文件的 Maven 插件

    有没有可以生成ISO镜像的maven插件 我需要获取一些模块的输出 主要是包含 jar 的 zip 文件 并将它们组合成一个 ISO 映像 Thanks 现在有一个 ISO9660 maven 插件可以完成这项工作 https github
  • 假布尔值=真?

    我在一本书中找到了这段代码 并在 Netbeans 中执行了它 boolean b false if b true System out println true else System out println false 我只是不明白为什
  • JPA ManyToMany 产生的空联接表

    我有一个应用程序 其中我尝试使用 Hibernate 作为 JPA 提供程序来实现两个实体之间的多对多关系 我正在尝试的例子是一个单向的 其中一个相机可以有多个镜头 而镜头可以安装到多个相机中 以下是我的实体类 只需粘贴其中的相关部分 Ca
  • Graphics2D setfont() 严重减慢了 java 应用程序的启动速度

    我正在用java制作一个游戏 它每秒刷新60次 每次执行循环时 我都会使用 g2d 来绘制图像和字符串 如果我这样做的话一切都会很好g2d setFont new Font Arial Font PLAIN 8 和抽绳 这将是正常的 但如果

随机推荐

  • 安卓中的人脸识别

    我需要在 Android 4 0 的应用程序中实现人脸识别登录 由于 Android Ice Cream Sandwich 中提供了人脸识别解锁功能 是否有任何开放的 SDK 或内置库来实现此功能 到目前为止 我遇到过外部 API 例如ht
  • Jenkins 管道 sh returnsstdout 不工作

    我正在尝试使用 Jenkins pipeline sh 命令的 returnStdout 功能 此处定义https jenkins io doc pipeline steps workflow durable task step code
  • JAR 文件:为什么提取然后压缩 JAR 文件会创建与原始大小不同的文件?

    我试图编辑提取的 Eclipse 插件 jar 文件中的单个字节 我注意到 在我将文件重新压缩为 jar 后 生成的文件比原始文件大 仅 1 并且该插件不起作用 Eclipse 已启动 但在选择工作区后静默关闭 回滚到原来的插件可以让它成功
  • 删除 index.php 并处理两个 Codeigniter 站点的子域(当其中一个站点位于另一个站点时)

    我有两个 Codeigniter 站点 一个位于另一个站点的子目录中 我需要一些帮助来修改我的 htaccess 文件以从两者中删除 index php 第一个站点 http subdomain domain com存储在 home sit
  • 将 2D 数组传递给 C++ 函数

    我有一个函数 我想将可变大小的二维数组作为参数 到目前为止我有这个 void myFunction double myArray myArray x y 5 etc 我在代码中的其他地方声明了一个数组 double anArray 10 1
  • 使用裁剪工具进行图像裁剪的 Django 应用程序

    我需要一个在客户端裁剪图像的应用程序 我的意思是 使用像 Jcrop jquery 插件这样的裁剪工具 我找到了这个工具 django 图像裁剪器 https github com marazmiki django image croppe
  • CUDA/PTX 32 位与 64 位

    CUDA 编译器可以选择生成 32 位或 64 位 PTX 这些有什么区别呢 是不是像 x86 一样 NVidia GPU 实际上也有 32 位和 64 位 ISA 还是仅与主机代码有关 指针肯定是最明显的区别 http docs nvid
  • NanoHTTPD - 将 https 流转换为 http

    为了克服 Chromecast 对来自自认证 https 服务器 在我的例子中是 Subsonic 音乐服务器 进行流传输的限制 我正在利用已经作为我的 Android 应用程序的一部分运行的 NanoHTTPD 服务器实例 这个想法是从
  • 如何在 Dart 中将 RxInt 转换为 Int ||扑?

    我正在玩扑扑 我遇到错误并且没有得到任何正确的解决方案 在我的应用程序中 我有一些可观察的变量GetX https pub dev packages get控制器 当尝试应用某种格式然后在此处获取日志时 Exception caught b
  • Maven 3.0.4 NoSuchMethod:... java.lang.NoSuchMethodError:com.google.common.collect.ImmutableSet.copyOf(..)

    我已经安装了Maven 3 0 4 with Homebrew每当我运行mvn命令我得到以下信息 Exception in thread main java lang NoSuchMethodError com google common
  • OkHttp 对请求启用/禁用 gzip 压缩

    我在用着Retrofit管理我的请求并希望进行一些测试来检查使用或不使用 gzip 的请求大小 默认情况下OkHttp对请求执行 gzip 压缩 或者必须使用拦截器 https github com square okhttp wiki I
  • jQuery 文档就绪与窗口加载冲突?

    我正在尝试拼凑一个视频库 我正在使用 jQuery 制作滑出面板 这很简单 我还使用 jQuery 来滚动缩略图 他们都工作得很好 问题是我需要滚动缩略图在滑出面板内工作 但事实并非如此 我认为这与文档准备好和窗口加载两个功能有关 我不确定
  • Ruby 中引发异常与抛出异常有什么区别?

    Ruby 有两种不同的异常机制 Throw Catch 和 Raise Rescue 为什么我们有两个 什么时候应该使用其中一种而不是另一种 raise fail rescue and ensure handle errors 也称为例外情
  • 如何以编程方式更新客户商店信用

    我正在使用 Magento 版本 1 9 1 1 我需要更新客户的商店信用余额 我知道可以在 Magento 管理界面中执行此操作 但就我而言 我需要向服务器发出 HTTP 请求 并且实际上执行与通过 Magento 管理界面执行的操作相同
  • 将brew安装的库包含到XCode中

    我正在尝试使用 Raylib 创建游戏 我想使用 XCode 因为我认为库管理会像 Windows 上的 Visual Studio 一样简单 我安装了这个库brew install raylib 现在我尝试运行这个从 Raylib 网站复
  • apollo graphql 响应数据中未显示“Extensions”字段

    这里有一个可重现的例子 https github com stonecold123 typegraphql test Run app js并在操场上导航http localhost 4000 graphql http localhost 4
  • VBA 中的编辑距离 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有包含数据的 Excel 工作表 我想获取它们之间的 Levenshtein 距离 我已经尝试导出为文
  • 使用 Python 2.7 的 HTML 解析树

    我试图为下面的 HTML 表配置一棵解析树 但无法形成它 我想看看树结构是什么样的 有人可以帮助我吗 p class title b The Dormouse s story b p p class story Once upon a ti
  • Python:BASIC 中是否有相当于中、右、左的词?

    我想做这样的事情 gt gt gt mystring foo gt gt gt print mid mystring Help 切片来救援 def left s amount return s amount def right s amou
  • iText 通过检查 CRL 来验证签名

    我正在设置一个验证器 可以检查签名的有效性 我所做的签名基于 DSS 级别 LT 因此文档中内置了撤销检查 我现在遇到的问题是在我在iText中开发的验证器层面 它允许验证签名的有效性以及撤销信息的有效性 根据我的研究 IText 允许基于