Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# iText7(.net)SignExternalSignatureContainer NullReferenceException_C#_Digital Signature_Nullreferenceexception_Itext7 - Fatal编程技术网

C# iText7(.net)SignExternalSignatureContainer NullReferenceException

C# iText7(.net)SignExternalSignatureContainer NullReferenceException,c#,digital-signature,nullreferenceexception,itext7,C#,Digital Signature,Nullreferenceexception,Itext7,我正在尝试创建一个能对PDF文档进行数字签名的C程序。为了将签名元素包含到PDF中,我使用了iText7。 现在,如果我在没有调试器的情况下运行程序,将抛出一个System.NullReferenceException,程序将失败。但是如果我用调试器运行程序,也会发生异常,代码会继续并正确地签署PDF 我不确定这是否是iText7的问题,或者我在创建签名字段时是否犯了错误或忘记了一些重要的事情 有什么办法解决这个问题吗 例外情况 System.NullReferenceException:Der

我正在尝试创建一个能对PDF文档进行数字签名的
C
程序。为了将签名元素包含到PDF中,我使用了
iText7
。 现在,如果我在没有调试器的情况下运行程序,将抛出一个
System.NullReferenceException
,程序将失败。但是如果我用调试器运行程序,也会发生异常,代码会继续并正确地签署PDF

我不确定这是否是
iText7
的问题,或者我在创建签名字段时是否犯了错误或忘记了一些重要的事情

有什么办法解决这个问题吗

例外情况

System.NullReferenceException:Der Objektverweis wurde nicht auf eine objektinstancez festgelegt。 在C:\Development\Others\itext7\iText\iText.sign\iText\Signatures\PdfSignatureAppearance.cs:Zeile 584中输入bei iText.Signatures.PdfSignatureAppearance.GetAppearance()。 C:\Development\Others\itext7\iText\iText.sign\iText\Signatures\PdfSigner.cs:Zeile 808中的bei iText.Signatures.PdfSigner.PreClose(IDictionary`2排除大小)。 在C:\Development\Others\itext7\iText\iText.sign\iText\Signatures\PdfSigner.SignExternalContainer(IExternalSignatureContainer-externalSignatureContainer,Int32 estimatedSize)中输入bei iText.Signatures.PdfSigner.SignExternalContainer(IExternalSignatureContainer,Int32 estimatedSize)。 C:\Development\Signature\SignService.Engine\Core\PdfEngine.AddSignature(SignTask任务)中的bei SignService.Engine.Core.PdfEngine.AddSignature(SignTask任务):Zeile 122

我的代码

/// <summary>
/// Add SignatureField to Pdf
/// and digitally sign it 
/// </summary>
public SignatureResult AddSignature(SignTask task)
{
    _logger.Info("Start Signing PDF");

    var prop = task.SignatureProperties;

    try
    {
        var reader = new PdfReader(new MemoryStream(prop.Document));
        var stream = new ByteArrayOutputStream();
        var signer = new PdfSigner(reader, stream, new StampingProperties().UseAppendMode());

        // set appearance
        var appearance = signer.GetSignatureAppearance();
        appearance.SetReason(prop.SignReason)
                  .SetLocation(prop.SignLocation)
                  .SetContact(prop.SignContact);

        // set rendering mode
        switch (_settings.Pdf.RenderingMode)
        {
            case SignatureRenderingMode.Description:
                appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
                break;
            case SignatureRenderingMode.Graphic:
                appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
                break;
            case SignatureRenderingMode.GraphicAndDescription:
                appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);
                break;
            case SignatureRenderingMode.NameAndDescription:
                appearance.SetRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);
                break;
        }

        // set image
        if (!string.IsNullOrEmpty(_settings.Pdf.SignatureGraphicPath))
        {
            if (File.Exists(_settings.Pdf.SignatureGraphicPath))
            {
                var imageData = ImageDataFactory.Create(_settings.Pdf.SignatureGraphicPath);
                appearance.SetSignatureGraphic(imageData);
            }
            else if (_settings.Pdf.RenderingMode == SignatureRenderingMode.GraphicAndDescription || _settings.Pdf.RenderingMode == SignatureRenderingMode.GraphicAndDescription)
            {
                throw new Exception("Failed to create Signature Field.\nIf rendering mode is graphic or graphic and description, a signature image must be provided");
            }
        }

        // set visibility
        if (prop.Visible)
        {
            var rect = new Rectangle(prop.X, prop.Y, prop.Width, prop.Height);
            appearance.SetPageRect(rect);
            appearance.SetPageNumber(1); // todo create setting for this
        }

        signer.SetFieldName(_settings.Pdf.SignatureFieldName);

        // sign field
        var signatureContainer = new ExternalSignatureContainer(task, _settings.Ais);
        // **Exeption thrown here**
        signer.SignExternalContainer(signatureContainer, GetEstimatedSize(task.TimestampOnly));

        var tempResult = stream.ToArray();

        // set revocation info if active
        if (tempResult.Length > 0 && _settings.Ais.AddRevocationInfo)
        {
            tempResult = AddRevocationInfo(signatureContainer.Crl, signatureContainer.Ocsp, tempResult);
        }

        reader.Close();
        stream.Close();

        _logger.Info("Finished signing");

        // return sign result
        return tempResult.Length > 0 
          ? new SignatureResult
          {
               Message = "",
               Status = RequestStatus.Success,
               Document = stream.ToArray(),
               Id = prop.Id
          }
          : new SignatureResult
          {
               Message = "Failed to sign the Document",
               Status = RequestStatus.Failed,
               Document = null,
               Id = prop.Id
          };
    }
    catch (AisServiceException aisServiceException)
    {
        _logger.Error($"While requesting Signature an error occured: {aisServiceException.Message}", aisServiceException);
        throw;
    }
    catch (Exception exception)
    {
        _logger.Error($"While creating signed pdf an error occured: {exception.Message}", exception);
        throw new PdfException($"While creating Signed Pdf an error Occured: {exception.Message}");
    }
}
任务:

{
  "Pdf": {
    "Visible": true,
    "Position": {
      "X": 50,
      "Y": 50,
      "Height": 100,
      "Width": 200
    },
    "SignatureFieldName": "SignatureField",
    "SignatureGraphicPath": "",
    "RenderingMode": 1
  }
}
  "SignatureProperties": {
    "Id": "1",
    "Document": [DocumentAsByteArray],
    "Visible": true,
    "SignReason": "Test",
    "SignLocation": "Test",
    "SignContact": "Test",
    "Height": 100,
    "Width": 200,
    "X": 50,
    "Y": 50
  }

在代码中,您没有使用
PdfSignatureAppearance.SetCertificate
设置签名者证书。对于像您这样的
SignExternalContainer
用例,iText确实不需要证书来执行实际的签名过程,但它确实需要证书来检索有关签名者的信息,以便将其用作名称,并在具有名称和/或描述的可见签名的情况下用于描述(即除纯
图形
外的任何渲染模式)

您的设置
“RenderingMode”:1
和堆栈跟踪
PdfSignatureAppearance.cs:Zeile 584
表明您处于
名称和描述
用例中。因此,iText尝试构建描述,访问其
签名证书
,并由于该成员为
null而失败

要解决此问题,请同时使用
PdfSignatureAppearance.SetCertificate
设置签名者证书

如果是
描述
图形和描述
,您也可以使用
PDFSignaturePearance.SetLayer2Text
将描述设置为预制值

但是,对于
NAME\u和\u DESCRIPTION
,iText无法插入预先计算好的名称


一个更通用的替代方法是自己创建签名外观,只需使用
GetLayer2
检索一个
PdfFormXObject
,您可以在其上绘制任何可视化效果。在这种情况下,iText不会尝试从证书中检索任何签名者信息。

问题发生在
PdfSignatureAppeara中nce.GetAppearance()
。这里创建了签名的可视化。因此,最可能的问题是iText需要一些信息来构建外观,并尝试从未设置的属性中检索。您的代码使用
\u设置
任务
信息填充许多属性。您能否共享t的特定值hem的签名运行失败。@mkl我用设置和任务更新了我的问题,我想如果我不需要“SignExternalContainer”的这些信息…但显然是这样。感谢您的帮助!正如答案中提到的,有很多方法可以满足证书的需要。但是如果您希望iText自动创建一个包含签名者信息的外观,那么只有证书可供使用。mhm另一个问题:此证书是否与签名pdf的证书相匹配之后?没有检查比较它们,在
SignExternalContainer
用例中,证书仅用于确定签名者的姓名和/或签名外观描述。因此,您可以使用不同的证书,但它应该以某种方式与实际签名者相关联,以产生合理的外观…P可能是发行人的证书?