当前位置: 首页 > 知识库问答 >
问题:

为硬件令牌数字签名添加时间戳,并添加LTV不工作/抛出异常

常飞翼
2023-03-14

这是这个问题的扩展问题:在pdf中添加撤销细节,同时对其进行签名

我已经用itextsharplibrary和。净核心(c#)。在签署pdf文件后,我使用上一个问题中的类添加了LTV直到这里pdf工作正常。

但当我试图在签名中嵌入时间戳时,它却在验证中嵌入了类的enable方法,它抛出异常:

签名人Sha256和1。2.840.10045.4.3.2未识别

以下是用于签名的代码方法:

private static byte[] SignPdfWithCert(X509Certificate2 cert, byte[] SourcePdfBytes, Guid userId, string password, int xPlace, int yPlace, int width, int height, int pageNo, string dscPin, Org.BouncyCastle.X509.X509Certificate[] chain, string algorithm, string itemId, Stream imageStream, int MarginXForDSCToSearchText = 5, int MarginYForDSCToSearchText = 5)
{
    var signature = new X509Certificate2Signature(cert, algorithm);

    PdfReader pdfReader;
    PdfReader.unethicalreading = true;
    if (!string.IsNullOrEmpty(password))
        pdfReader = new PdfReader(SourcePdfBytes, Encoding.ASCII.GetBytes(password));
    else
        pdfReader = new PdfReader(SourcePdfBytes);
    MemoryStream signedPdf = new MemoryStream();
    PdfStamper pdfStamper;

    pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0', null, true); // Append new digital signature

    if (string.IsNullOrEmpty(password) == false)
    {
        pdfStamper.SetEncryption(Encoding.ASCII.GetBytes(password), Encoding.ASCII.GetBytes(password), PdfWriter.AllowCopy, PdfWriter.ENCRYPTION_AES_256);
    }

    PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance;

    signatureAppearance.Location = cert.IssuerName.Name;
    signatureAppearance.Acro6Layers = false;
    signatureAppearance.Layer4Text = PdfSignatureAppearance.questionMark;  //Property neeeds to be set for watermarking behind the signature which indicates signature status as per User's computer. 
    if (imageStream != null)
    {
        signatureAppearance.Layer2Text = "";
        var image = iTextSharp.text.Image.GetInstance(imageStream);
        signatureAppearance.SignatureGraphic = image;
        signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC;
    }
    else
    {
        signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
    }
    signatureAppearance.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;

    signatureAppearance.SetVisibleSignature(new iTextSharp.text.Rectangle(xPlace, yPlace, xPlace + width, yPlace + height), pageNo, string.Concat(itemId, pageNo));

    RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;

    CspParameters cspp = new CspParameters();
    cspp.KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName;
    cspp.ProviderName = rsa.CspKeyContainerInfo.ProviderName;
    // cspp.ProviderName = "Microsoft Smart Card Key Storage Provider";

    cspp.ProviderType = rsa.CspKeyContainerInfo.ProviderType;
    SecureString pwd = GetSecurePin(dscPin);
    cspp.KeyPassword = pwd;
    cspp.Flags = CspProviderFlags.NoPrompt;

    try
    {
        RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(cspp);
    }
    catch
    {
        // ignored- pfx file
    }

    rsa.PersistKeyInCsp = true;
    var url = "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23";
    var tsc = new TSAClientBouncyCastle(url, null, null, 4096, "SHA-512");
    MakeSignature.SignDetached(signatureAppearance, signature, chain, null, null, tsc, 0, CryptoStandard.CADES);

    SourcePdfBytes = signedPdf.ToArray();
    pdfStamper.Close();
    var directory = System.AppDomain.CurrentDomain.BaseDirectory;
    var finaltrustedSignedpdf = Path.Combine(directory, "TempFolder", Guid.NewGuid().ToString());
    if (!Directory.Exists(finaltrustedSignedpdf))
    {
        Directory.CreateDirectory(finaltrustedSignedpdf);
    }
    finaltrustedSignedpdf = Path.Combine(finaltrustedSignedpdf, "LTVSignedpdf.pdf");
    try
    {
        AddLtv(SourcePdfBytes, finaltrustedSignedpdf, new OcspClientBouncyCastle(), new CrlClientOnline());
        var readbytes = File.ReadAllBytes(finaltrustedSignedpdf);
        if (File.Exists(finaltrustedSignedpdf))
        {
            File.Delete(finaltrustedSignedpdf);
        }
        return readbytes;
    }
    catch
    {
        //Unable to add LTV due to no access on CRL URL
        return SourcePdfBytes;
    }
}

public static void AddLtv(byte[] src, string dest, IOcspClient ocsp, ICrlClient crl)
{
    PdfReader reader = new PdfReader(src);
    FileStream os = new FileStream(dest, FileMode.CreateNew);
    PdfStamper pdfStamper = new PdfStamper(reader, os, (char)0, true);

    AdobeLtvEnabling adobeLtvEnabling = new AdobeLtvEnabling(pdfStamper);
    adobeLtvEnabling.enable(ocsp, crl);
    pdfStamper.Close();
}

它使用上一个问题中的类,我在上面的代码中使用了随机的免费时间戳url,因为我的签名证书在证书或证书证书的证书详细信息中没有时间戳预配的url。

这是导出的cer文件,没有证书的私钥

在上面的代码中,如果我们删除下面的行

var url = "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23";
            var tsc = new TSAClientBouncyCastle(url, null, null, 4096, "SHA-512");
            MakeSignature.SignDetached(signatureAppearance, signature, chain, null, null, tsc, 0, CryptoStandard.CADES); 

用这句话

MakeSignature.SignDetached(signatureAppearance, signature, chain, null, null, null, 0, CryptoStandard.CADES);

然后它将生成带签名的pdf,没有时间戳。-这是ltv启用和绿色刻度标记。

这是另一个没有使用不同证书令牌的时间戳的已签名pdf:-对于此文件,时间戳在CA证书中提供,在签名中添加时间戳时应使用CA证书。我没有那个令牌的导出DSC文件。

请指导我以下-1。它为什么抛出异常以及它的建议是什么?添加时间戳的方法正确吗?如果CA证书2中没有时间戳url,我可以使用免费开放的时间戳服务吗。如果时间戳URL存在于CA证书中,那么如何在代码对象中访问该URL。-我们这里没有这样的令牌,上面的签名pdf中使用了这种令牌。

提前谢谢。如果我哪里做错了,请纠正我。

更新:例外:签名者SHA256WITH1。2.840.10045.4.3.2未识别。

Stacktrace:

   at Org.BouncyCastle.Security.SignerUtilities.GetSigner(String algorithm)
   at iTextSharp.text.pdf.security.PdfPKCS7.InitSignature(AsymmetricKeyParameter key)
   at iTextSharp.text.pdf.security.PdfPKCS7..ctor(Byte[] contentsKey, PdfName filterSubtype)
   at iTextSharp.text.pdf.AcroFields.VerifySignature(String name)
   at Cygnature.App.AdobeLtvEnabling.enable(IOcspClient ocspClient, ICrlClient crlClient) in D:\WorkSpace\Aug2019\Cygnature.Utility\CygnetGSPDSC\AdobeLTVEnabling.cs:line 43
   at Cygnature.App.DigitalSignatureSigningService.AddLtv(Byte[] src, String dest, IOcspClient ocsp, ICrlClient crl) in D:\WorkSpace\Aug2019\Cygnature.Utility\CygnetGSPDSC\DigitalSignatureSigningService.cs:line 557
   at Cygnature.App.DigitalSignatureSigningService.SignPdfWithCert(X509Certificate2 cert, Byte[] SourcePdfBytes, Guid userId, String password, Int32 xPlace, Int32 yPlace, Int32 width, Int32 height, Int32 pageNo, String dscPin, X509Certificate[] chain, String algorithm, String itemId, Stream imageStream, Int32 MarginXForDSCToSearchText, Int32 MarginYForDSCToSearchText) in D:\WorkSpace\Aug2019\Cygnature.Utility\CygnetGSPDSC\DigitalSignatureSigningService.cs:line 531

共有2个答案

段干开宇
2023-03-14

在她自己的回答中,OP明确表示,在为她的用例切换到正确的关键材料后,异常消失了。

这个问题的答案是,如果一个人确实需要使用的关键材料出现异常,该怎么办。

异常有消息"Signer SHA256WITH1.2.840.10045.4.3.2不被识别"和堆栈跟踪

at Org.BouncyCastle.Security.SignerUtilities.GetSigner(String algorithm)
at iTextSharp.text.pdf.security.PdfPKCS7.InitSignature(AsymmetricKeyParameter key)
at iTextSharp.text.pdf.security.PdfPKCS7..ctor(Byte[] contentsKey, PdfName filterSubtype)
at iTextSharp.text.pdf.AcroFields.VerifySignature(String name)

它发生在iText类PdfPKCS7的初始化过程中,该类请求签名者使用无效的算法名称"SHA256WITH1.2.840.10045.4.3.2"。OID 1.2.840.10045.4.3.2代表ecdsa-with-SHA256,这说明了错误的原因:所讨论的签名是椭圆曲线签名,但iText 5. x不支持ECDSA算法。

LTV启用这样的签名使用ADOBELITVEnable类(从这个答案)尽管如此,我们,因此,必须删除使用PdfPKCS7在它。

我们用更通用的BouncyCastle类替换它,如下所示,在方法enablereplace the loop中

List<String> names = fields.GetSignatureNames();
foreach (String name in names)
{
    PdfPKCS7 pdfPKCS7 = fields.VerifySignature(name);
    PdfDictionary signatureDictionary = fields.GetSignatureDictionary(name);
    X509Certificate certificate = pdfPKCS7.SigningCertificate;
    addLtvForChain(certificate, ocspClient, crlClient, getSignatureHashKey(signatureDictionary, encrypted));
}

通过

List<String> names = fields.GetSignatureNames();
foreach (String name in names)
{
    PdfDictionary signatureDictionary = fields.GetSignatureDictionary(name);
    PdfString contents = signatureDictionary.GetAsString(PdfName.CONTENTS);
    CmsSignedData signedData = new CmsSignedData(contents.GetOriginalBytes());
    IX509Store certs = signedData.GetCertificates("COLLECTION");
    foreach (SignerInformation signerInformation in signedData.GetSignerInfos().GetSigners())
    {
        ArrayList certList = new ArrayList(certs.GetMatches(signerInformation.SignerID));
        X509Certificate certificate = (X509Certificate)certList[0];
        addLtvForChain(certificate, ocspClient, crlClient, getSignatureHashKey(signatureDictionary, encrypted));
    }
}

现在支持更广泛的签名算法,实际上比Adobe Reader支持的更广泛。

萧宣
2023-03-14

我尝试使用错误的DSC(USB令牌)和时间戳URL。这就是它在添加LTV时向我抛出异常的原因。

然后我试着在x509扩展的属性中嵌入实际的全局符号dsc和url,然后它工作了,我能够在PDF:zeta uploader上签名。com/browse/897639557

获取时间戳URL的参考代码:

  X509Certificate2 cert = null;


  X509Store x509Store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
  x509Store.Open(OpenFlags.ReadWrite);

   //manually chose the certificate in the store
  Selectcert: X509Certificate2Collection select = X509Certificate2UI.SelectFromCollection(x509Store.Certificates, null, null, X509SelectionFlag.SingleSelection);

   if (select.Count > 0)
   cert = select[0]; //This will get us the selected certificate in "cert" object

foreach (System.Security.Cryptography.X509Certificates.X509Extension extension in cert.Extensions)
                {
                    if (extension.Oid.Value == "1.2.840.113583.1.1.9.1")
                    {
                        var ext = extension;
                        AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData);
                        var rawdata = asndata.RawData;
                        var val = Encoding.Default.GetString(rawdata);
                        var timestampUrl = TrimNonAscii(val);
                        timestampUrl = timestampUrl.Substring(timestampUrl.IndexOf("http"));
                    }
                }

在make签名中添加时间戳的代码

  var tsc = new TSAClientBouncyCastle(timestampUrl , null, null, 4096, "SHA-512");  
  //here timestamp url is fetched from above code
  MakeSignature.SignDetached(signatureAppearance, signature, chain, null, null, tsc, 
  0, CryptoStandard.CADES);
 类似资料:
  • 我正在使用iText 5.5.3来签署PDF文档。我需要这些文件是时间戳和LTV启用。我按照说明使用addLtv方法(代码示例5.9,Lowagie白皮书第137页)。我得到一个带有2个签名的PDF,这是正常的:第一个是我自己的签名,第二个是文档级时间戳。 但是,Acrobat告诉我我的签名启用了LTV,但时间戳签名没有: 图片来自Acrobat Pro XIhttp://img15.hostin

  • 我是新来的iText 7,我已经尝试添加ltv信息到现有的签名通过使用addolv()方法(下面提供的代码)...如果我理解正确的话,这个方法将crl或ocsp参数添加到现有的签名或时间戳中,然后对文档进行时间戳,但是生成的pdf文档没有启用ltv。然而,如果我首先用ocsp或crl列表签署文档,我就能够生成支持LTV的签名,这让我相信这个问题与某些证书丢失或未正确添加无关。因此,由于某种原因,a

  • 问题内容: 我想将时间戳添加到我的PDF文档中(不带数字签名)。我怎样才能做到这一点? 我可以使用Itext使用数字签名来做到这一点(我在这里有TSAClient): 但是在没有数字签名的情况下如何做类似的事情?使用Bouncy Castle或Itext或Pdfbox …或其他库。 问题答案: 在iText中,您正在寻找 也比照。JavaDoc文档: 您可能需要阅读章节5.4.1 在数字签名中为P

  • 问题内容: 我无法为Java时间戳添加秒数。 我有这个,但是,它给了我相同的日期: 问题答案: 您拥有的代码适合我。作为简短但完整的程序: 输出: 请注意相差10分钟,即600秒。 当然,这样会损失亚毫秒级的精度,这可能不太理想-最初与我通常使用的时间戳背道而驰-但这 确实 增加了秒数… 另一种选择是直接使用:

  • 在下面的过程中,我得到了一个错误。我意识到这个错误似乎是抛出的,因为它试图读取分区(rec)中的整个记录,但试图将其分配给字符串(Str=jsonArray.toJSONString();)同时我使用5秒的批处理间隔火花流配置。对这段代码有什么建议吗?请好心帮忙。谢啦 错误在这一行: 以下是我的全部功能:

  • 问题内容: 我将csv文件读入pandas数据框,得到以下信息: 无论是和列有100个元素。我想将Hour的相应元素添加到TDate。 我尝试了以下方法: 但是我得到了错误,因为td似乎没有将array作为参数。如何将的每个元素添加到的相应元素中。 问题答案: 我想你可以添加到列列转换有: