iTextSharp 5.5.6:使用SwissSign USB令牌签名无效

时间:2015-08-31 19:23:56

标签: itextsharp

我读过Bruno Lowagie的白皮书:PDF文档的数字签名。

我按照示例进行操作,然后使用MSCAPI用SwissSign USB令牌签署了PDF文件。这行代码可以解决问题:

MakeSignature.SignDetached(外观,pks,chain,crlList,ocspClient,tsaClient,estimatedSize,subfilter);

我也使用SwissSign TSA URL传递TSA客户端:tsa(dot)swisssign(dot)net

当我在Acrobat Reader DC 2015中打开签名的PDF时,我收到错误:

签名无效。

此签名中包含的格式或信息存在错误

签名者的身份尚未经过验证

签名时间来自签名者计算机上的时钟。

使用SwissSign工具签名PDF时,一切看起来都很好:签名有效。

我把PDF放在这里:

invalid PDF - signed with iTextSharp 5.5.6

valid PDF - signed with SwissSign tool

我尝试过不同的哈希算法组合,但没有成功。我错过了什么?

任何帮助表示感谢。

最诚挚的问候,

菲尔

以下是完整代码:

    private void _sign_Click(object sender, RoutedEventArgs e)
    {
        X509Store x509Store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        x509Store.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certificates = x509Store.Certificates;
        IList<Org.BouncyCastle.X509.X509Certificate> chain = new List<Org.BouncyCastle.X509.X509Certificate>();
        X509Certificate2 pk = null;
        if (certificates.Count > 0)
        {
            for (int i = 0; i < certificates.Count; i++)
            {
                if (certificates[i].FriendlyName == "Philipp Egger (Qualified Signature) .....")        // Phil Egger Signature Certificate
                {
                    pk = certificates[i];
                    break;
                }
            }

            X509Chain x509chain = new X509Chain();
            x509chain.Build(pk);

            foreach (X509ChainElement x509ChainElement in x509chain.ChainElements)
            {
                chain.Add(Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate));
            }
        }
        x509Store.Close();

        if (pk != null)
        {
            #region connect usb token
            ///////////////////
            RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)pk.PrivateKey;

            CspParameters cspp = new CspParameters();
            cspp.KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName;
            cspp.ProviderName = rsa.CspKeyContainerInfo.ProviderName;
            cspp.ProviderType = rsa.CspKeyContainerInfo.ProviderType;

            cspp.Flags = CspProviderFlags.NoPrompt;
            System.Security.SecureString pwstr = new System.Security.SecureString();
            pwstr.AppendChar('x');
            pwstr.AppendChar('x');
            pwstr.AppendChar('x');
            cspp.KeyPassword = pwstr;

            RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(cspp);
            rsa2.PersistKeyInCsp = true;
            // PIN is cached from now on and popup won't appear
            ///////////////////////
            #endregion

            IOcspClient ocspClient = new OcspClientBouncyCastle();
            ITSAClient tsaClient = null;
            for (int i = 0; i < chain.Count; i++)
            {
                Org.BouncyCastle.X509.X509Certificate cert = chain[i];
                String tsaUrl = CertificateUtil.GetTSAURL(cert);
                if (tsaUrl != null)
                {
                    tsaClient = new TSAClientBouncyCastle(tsaUrl);
                    break;
                }
            }

            if (tsaClient == null)
            { 
                tsaClient = new TSAClientBouncyCastle("http://tsa.swisssign.net");
                //tsaClient = new MyTSAClientBouncyCastle("http://tsa.swisssign.net");      // set user-agent
            }

            IList<ICrlClient> crlList = new List<ICrlClient>();
            crlList.Add(new CrlClientOnline(chain));

            string pathSource = @"C:\Temp\test_to_sign.pdf";
            string pathTarget3 = @"C:\Temp\test_to_sign-signed3.pdf";

            // this.SignNew(pathSource, pathTarget1, chain, pk, DigestAlgorithms.SHA1, CryptoStandard.CMS, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget2, chain, pk, DigestAlgorithms.SHA1, CryptoStandard.CADES, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            this.SignNew(pathSource, pathTarget3, chain, pk, DigestAlgorithms.SHA256, CryptoStandard.CMS, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget4, chain, pk, DigestAlgorithms.SHA256, CryptoStandard.CADES, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget5, chain, pk, DigestAlgorithms.SHA384, CryptoStandard.CMS, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget6, chain, pk, DigestAlgorithms.SHA384, CryptoStandard.CADES, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget7, chain, pk, DigestAlgorithms.SHA512, CryptoStandard.CMS, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);
            // this.SignNew(pathSource, pathTarget8, chain, pk, DigestAlgorithms.SHA512, CryptoStandard.CADES, "Test", "Rheinau", crlList, ocspClient, tsaClient, 0);

            this._txt.Text = "Signed successfully.";
        }
        else
        {
            this._txt.Text = "Certificate not found.";
        }
    }

    public void SignNew(String src, String dest,
             ICollection<Org.BouncyCastle.X509.X509Certificate> chain, X509Certificate2 pk,
             String digestAlgorithm, CryptoStandard subfilter,
             String reason, String location,
             ICollection<ICrlClient> crlList,
             IOcspClient ocspClient,
             ITSAClient tsaClient,
             int estimatedSize)
    {
        // Creating the reader and the stamper
        PdfReader reader = null;
        PdfStamper stamper = null;
        FileStream os = null;
        try
        {
            reader = new PdfReader(src);
            os = new FileStream(dest, FileMode.Create);
            stamper = PdfStamper.CreateSignature(reader, os, '\0');
            // Creating the appearance
            PdfSignatureAppearance appearance = stamper.SignatureAppearance;
            appearance.Reason = reason;
            appearance.Location = location;
            appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(36, 748, 144, 780), 1, "Signature1");
            // Creating the signature
            IExternalSignature pks = new X509Certificate2Signature(pk, digestAlgorithm);
            MakeSignature.SignDetached(appearance, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
        }
        catch (Exception e)
        {
            this._txt.Text = e.Message;
        }
        finally
        {
            if (reader != null)
                reader.Close();
            if (stamper != null)
                stamper.Close();
            if (os != null)
                os.Close();
        }
    }

1 个答案:

答案 0 :(得分:0)

问题在于它显然是SwissSign CSP(加密服务提供商;在Windows系统存储和硬件设备之间提供桥接的层),它在使用MSCAPI时选择了错误的私钥。

似乎没有办法在MSCAPI中选择正确的私钥。

因此,我决定使用PKCS11和NCryptroki库。代码如下:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,15}$