C# iTextSharp中具有延迟签名的证书链

C# iTextSharp中具有延迟签名的证书链,c#,pdf,itextsharp,itext,pkcs#7,C#,Pdf,Itextsharp,Itext,Pkcs#7,我正在使用移动签名服务签署PDF文档。在服务对文档的散列签名后,我收到了来自服务的证书。我能够用证书替换文档中的零填充签名容器,没有任何问题,但是我在包含证书链方面遇到了问题 我在应用程序中有根证书、中间证书和叶证书,但我不能将它们包含在签名中。我想我能做的是在代码中创建一个链,然后从该链中注入编码的字节,但这会导致一个无效的证书 我使用的代码如下所示: X509CertificateParser cp = new X509CertificateParser(); var certFromSe

我正在使用移动签名服务签署PDF文档。在服务对文档的散列签名后,我收到了来自服务的证书。我能够用证书替换文档中的零填充签名容器,没有任何问题,但是我在包含证书链方面遇到了问题

我在应用程序中有根证书、中间证书和叶证书,但我不能将它们包含在签名中。我想我能做的是在代码中创建一个链,然后从该链中注入编码的字节,但这会导致一个无效的证书

我使用的代码如下所示:

X509CertificateParser cp = new X509CertificateParser();

var certFromServer = getCertFromServer();

var rootCert = cp.ReadCertificate(new X509Certificate2(rootCertPath).RawData);
var interCert = cp.ReadCertificate(new X509Certificate2(interCertPath)RawData);
var leafCert = cp.ReadCertificate(new X509Certificate2(leafCertPath).RawData);

List<X509Certificate> intermediateCerts = new List<X509Certificate> {
    interCert, 
    leafCert
};

X509CertificateParser parser = new X509CertificateParser();
PkixCertPathBuilder builder = new PkixCertPathBuilder();

X509CertStoreSelector holder = new X509CertStoreSelector {
    Certificate = parser.ReadCertificate(certFromServer)
};

intermediateCerts.Add(holder.Certificate);

HashSet rootCerts = new HashSet {new TrustAnchor(rootCert, null)};

PkixBuilderParameters builderParams = new PkixBuilderParameters(rootCerts, holder)
    {
        IsRevocationEnabled = false
    };

X509CollectionStoreParameters intermediateStoreParameters =
    new X509CollectionStoreParameters(intermediateCerts);

builderParams.AddStore(X509StoreFactory.Create(
    "Certificate/Collection", intermediateStoreParameters)
);

PkixCertPathBuilderResult result = builder.Build(builderParams);


byte[] certChainBytes = result.CertPath.GetEncoded("PKCS7"); 

// ExternalSignatureContainer is a container that simply returns the cert bytes 
// from its Sign method without changing them.
IExternalSignatureContainer container = new ExternalSignatureContainer(certChainBytes);

MakeSignature.SignDeferred(reader, _signatureFieldName, baos, container);
X509CertificateParser cp=新的X509CertificateParser();
var certFromServer=getCertFromServer();
var rootCert=cp.ReadCertificate(新的X509Certificate2(rootCertPath).RawData);
var interCert=cp.ReadCertificate(新的X509Certificate2(interCertPath)原始数据);
var leafCert=cp.ReadCertificate(新的X509Certificate2(leafCertPath).RawData);
List intermediateCerts=新列表{
插入,
叶蝉
};
X509CertificateParser=新的X509CertificateParser();
PkixCertPathBuilder=新的PkixCertPathBuilder();
X509CertStoreSelector支架=新X509CertStoreSelector{
Certificate=parser.ReadCertificate(certFromServer)
};
中级证书。添加(持有人证书);
HashSet rootCerts=newhashset{new TrustAnchor(rootCert,null)};
PkixBuilderParameters builderParams=新的PkixBuilderParameters(根证书,持有者)
{
IsRevocationEnabled=错误
};
X509采集存储参数中间存储重新参数=
新的X509CollectionStoreParameters(intermediateCerts);
builderParams.AddStore(X509StoreFactory.Create(
“证书/集合”,中间人(重新参数)
);
PkixCertPathBuilderResult结果=builder.Build(builderParams);
byte[]certChainBytes=result.CertPath.GetEncoded(“PKCS7”);
//ExternalSignatureContainer是一个只返回证书字节的容器
//从它的符号方法,而不改变它们。
IExternalSignatureContainer=新的ExternalSignatureContainer(certChainBytes);
MakeSignature.SignDeferred(reader,_signatureFieldName,baos,container);
创建链的方法来自以下StackOverflow问题:


在iTextSharp中为签名容器构建证书链的正确方法是什么?

ExternalSignatureContainer是一个容器,它只从其签名方法返回证书字节,而不更改它们。-但是
Sign
方法将返回一个包含签名和其他对象的容器;您似乎没有插入因此,请彻底检查
ExternalSignatureContainer
以返回一个包含签名和证书的容器。
Sign
方法返回一个字节数组。我找不到任何关于如何创建证书容器然后基于它返回字节数组的示例。那么我该怎么做呢实际创建这些对象的容器?我想我现在正在做的是
Sign
方法应该做的事情,但我想我错了。-如果我简单地创建
externalsignaturecanier
,将服务器的单个证书作为参数,然后在
Sign
方法。
Sign
方法应返回要嵌入的签名容器。通常(除非您使用的是adbe.x509.rsa_sha1或其他专有工具),这是一个PKCS#7或CMS容器(非常类似),其中包含证书和一个(立即的)SignerInfo结构,该结构又包含基本签名。根据您的移动签名服务实际返回的是PKCS#7/CMS签名容器还是仅返回PKCS#1签名,您必须查看如何使用证书增强现有容器或从头开始构建容器。返回此增强/新建容器。感谢r评论。事实证明,我实际上从服务中收到了一个PKCS#7容器。我花了几个小时研究了如何在没有任何运气的情况下使用证书来增强现有容器。你知道这是如何实现的吗?或者如果是这样的话?我觉得这可能是一个新问题的素材,因为这不是特定于iText的。我习惯于使用不同的安全库(专有库),因此,我对bc不太了解。因此,请将其本身作为一个问题。但是,您是否已经检查了从该服务获得的容器中已包含哪些证书?