我閱讀Bruno Lowagie的白皮書:PDF文檔的數字簽名。iTextSharp 5.5.6:使用SwissSign USB令牌簽名無效
我遵循這些例子,我可以用我的SwissSign USB令牌使用MSCAPI簽署PDF。這行代碼有訣竅:
MakeSignature.SignDetached(appearance,pks,chain,crlList,ocspClient,tsaClient,estimatedSize,subfilter);
我也是經過TSA客戶端與SwissSign TSA網址:TSA(點)swisssign(點)淨
當我打開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();
}
}
SwissSign工具內部也使用iText(夏普)。因此,您如何使用iTextSharp簽名API有些問題。從您提供的單一代碼行中無法推斷出任何東西。因此,請提供更多代碼。此外,你已經簽署了包括一個巨大的CRL和一個時間戳。爲什麼不從簡單開始,首先創建一個沒有這些添加的簽名,並在基本工作後儘快添加它們? – mkl
@mkl:謝謝你的回覆。是的,關於CRL - >我在重構iTextSharp中的同一個列表時與使用SwissSign工具簽名時一樣。 – Fitsch
好的,但你有沒有嘗試過一次沒有名單?如果你這樣做,是否成功併產生Adobe Reader接受的簽名? – mkl