PDFBox 库从已签名的 PDF 中读取不可见的 PDFSignature ..未显示签名者姓名
PDFBox Library to read Invisible PDFSignature from Signed PDF..Signer name is not shown
对于带有不可见签名的已签名 PDF 文档,我正在使用 PDFBox 库来提取签名者信息,但它为空。相同的代码适用于可见签名。如果我们需要制作,有人可以帮忙吗?
//Load PDF Document
PDDocument document = PDDocument.load(doc);
//Iterate each Signature
for (PDSignature pdSignature : document.getSignatureDictionaries()) {
if (pdSignature != null) {
HashMap values = new HashMap();
String subFilter = pdSignature.getSubFilter();
if (subFilter != null) {
LOG.debug("---------Siganature Details---------- ");
LOG.debug("Signer Name : " + pdSignature.getName());
values.put(SignerName, pdSignature.getName());
pdSignature.getName()
returns 签名字典的 Name 条目的值。但此条目是可选的:
Name text string (Optional) The name of the person or authority signing the document.
This value should be used only when it is not possible to extract the name from the signature.
通常您必须分析嵌入式签名容器中的签名者证书以获得签名者的通用名称。
正如@Tilman 在评论中指出的那样,pdfbox 示例ShowSignature 展示了多种从 CMS 签名容器中检索数据的方法。
关于您的评论
在您写的评论中
Only the complete principal string can be extracted which contains the complete string using the below code "certFromSignedData.getSubjectX500Principal().toString()" [...] Any direct way of querying CN name alone?
实际上,如果您将 toString()
应用于 certFromSignedData.getSubjectX500Principal()
返回的 X500Principal
,您只会获得完整的主题专有名称。但是如果你为它创建一个sun.security.x509.X500Name
,你可以很容易地检索到通用名称:
X500Principal principal = certFromSignedData.getSubjectX500Principal();
sun.security.x509.X500Name name = sun.security.x509.X500Name.asX500Name(principal);
System.out.printf("Whole DN: %s\n", name);
System.out.printf("CN: %s\n", name.getCommonName());
如果不想使用sun.security.x509
类,同样可以使用BouncyCastle类,从匹配的BouncyCastleX509CertificateHolder
:[=23=开始]
org.bouncycastle.asn1.x500.X500Name name = certificateHolder.getSubject();
System.out.printf("Whole DN: %s\n", name);
RDN[] cns = name.getRDNs(BCStyle.CN);
System.out.printf("CN: %s\n", cns.length > 0 ? cns[0].getFirst().getValue() : null);
however it's in different format for invisible and visible signature. For visible signature: SERIALNUMBER=xxxx, DNQ=xxx, EMAILADDRESS=xx, SURNAME=xx, GIVENNAME=xx, C=xx, CN=xx and for invisible signature "CN="xx" + EMAILADDRESS=xx, OU=xx, O="xx", L=xx, ST=xx, C=xx".
subject DN使用哪些属性,是否使用多attribute/value对的RDN,仅取决于签名者证书,与可见和不可见签名无关。如果您对不可见和可见签名有不同的特定模式,那么您的测试 PDF 池就有偏差。
对于带有不可见签名的已签名 PDF 文档,我正在使用 PDFBox 库来提取签名者信息,但它为空。相同的代码适用于可见签名。如果我们需要制作,有人可以帮忙吗?
//Load PDF Document
PDDocument document = PDDocument.load(doc);
//Iterate each Signature
for (PDSignature pdSignature : document.getSignatureDictionaries()) {
if (pdSignature != null) {
HashMap values = new HashMap();
String subFilter = pdSignature.getSubFilter();
if (subFilter != null) {
LOG.debug("---------Siganature Details---------- ");
LOG.debug("Signer Name : " + pdSignature.getName());
values.put(SignerName, pdSignature.getName());
pdSignature.getName()
returns 签名字典的 Name 条目的值。但此条目是可选的:
Name text string (Optional) The name of the person or authority signing the document. This value should be used only when it is not possible to extract the name from the signature.
通常您必须分析嵌入式签名容器中的签名者证书以获得签名者的通用名称。
正如@Tilman 在评论中指出的那样,pdfbox 示例ShowSignature 展示了多种从 CMS 签名容器中检索数据的方法。
关于您的评论
在您写的评论中
Only the complete principal string can be extracted which contains the complete string using the below code "certFromSignedData.getSubjectX500Principal().toString()" [...] Any direct way of querying CN name alone?
实际上,如果您将 toString()
应用于 certFromSignedData.getSubjectX500Principal()
返回的 X500Principal
,您只会获得完整的主题专有名称。但是如果你为它创建一个sun.security.x509.X500Name
,你可以很容易地检索到通用名称:
X500Principal principal = certFromSignedData.getSubjectX500Principal();
sun.security.x509.X500Name name = sun.security.x509.X500Name.asX500Name(principal);
System.out.printf("Whole DN: %s\n", name);
System.out.printf("CN: %s\n", name.getCommonName());
如果不想使用sun.security.x509
类,同样可以使用BouncyCastle类,从匹配的BouncyCastleX509CertificateHolder
:[=23=开始]
org.bouncycastle.asn1.x500.X500Name name = certificateHolder.getSubject();
System.out.printf("Whole DN: %s\n", name);
RDN[] cns = name.getRDNs(BCStyle.CN);
System.out.printf("CN: %s\n", cns.length > 0 ? cns[0].getFirst().getValue() : null);
however it's in different format for invisible and visible signature. For visible signature: SERIALNUMBER=xxxx, DNQ=xxx, EMAILADDRESS=xx, SURNAME=xx, GIVENNAME=xx, C=xx, CN=xx and for invisible signature "CN="xx" + EMAILADDRESS=xx, OU=xx, O="xx", L=xx, ST=xx, C=xx".
subject DN使用哪些属性,是否使用多attribute/value对的RDN,仅取决于签名者证书,与可见和不可见签名无关。如果您对不可见和可见签名有不同的特定模式,那么您的测试 PDF 池就有偏差。