C# iTextSharp由字段签名
我(终于)能够用我的签名制作一个签名的PDF,但我一生都无法计算“签名人”字段。只有3个字段,联系人、原因、位置。其他字段为日期和签名人。我不确定日期是如何填写的。您可以看到,我尝试了几个明显的签名者字段,但没有soap 我在写我的代码,以防它对其他人有帮助……我花了一段时间才弄明白这一点C# iTextSharp由字段签名,c#,itext,C#,Itext,我(终于)能够用我的签名制作一个签名的PDF,但我一生都无法计算“签名人”字段。只有3个字段,联系人、原因、位置。其他字段为日期和签名人。我不确定日期是如何填写的。您可以看到,我尝试了几个明显的签名者字段,但没有soap 我在写我的代码,以防它对其他人有帮助……我花了一段时间才弄明白这一点 static private void SignIt() { // Creating the reader and the stamper PdfReader reader = null;
static private void SignIt()
{
// Creating the reader and the stamper
PdfReader reader = null;
PdfStamper stamper = null;
FileStream os = null;
try
{
string sigFileName = "c:\\temp\\signature.jpg";
string inputFile = "C:\\temp\\mypdf.pdf";
string outputFile = "C:\\temp\\mypdfsigned.pdf";
string certFileName = "c:\\temp\\adcl.pfx";
string certPassword = "adcl214";
StringBuilder sb = new StringBuilder();
PdfReader myReader = new PdfReader(inputFile);
reader = new PdfReader(inputFile);
os = new FileStream(outputFile, FileMode.Create);
//Activate MultiSignatures
stamper = PdfStamper.CreateSignature(reader, os, '\0', null, true);
//To disable Multi signatures uncomment this line : every new signature will invalidate older ones !
//stamper = PdfStamper.CreateSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
Rectangle rectangle = new Rectangle(275, 25, 500, 100);
appearance.SetVisibleSignature(rectangle, 1, "Revision " + 1 + "|" + 1);
appearance.SignatureCreator = "Robert Dejournett, PhD";
appearance.Reason = "Signed";
appearance.Location = "MD Anderson Cancer Center";
appearance.Contact = "Robert Dejournett";
appearance.Layer2Text = "Signed on " + DateTime.Now;
appearance.SignatureRenderingMode = iTextSharp.text.pdf.PdfSignatureAppearance.RenderingMode.DESCRIPTION;
PdfTemplate n2 = appearance.GetLayer(2);
n2.AddImage(AddSignatureImage(sigFileName));
// generate cert file
if (!System.IO.File.Exists(certFileName)) GenerateCertToFile(certFileName, certPassword);
// do needful to get cert info
Pkcs12Store store = new Pkcs12Store(new FileStream(certFileName, FileMode.Open), certPassword.ToCharArray());
ICollection<Org.BouncyCastle.X509.X509Certificate> chain = new List<Org.BouncyCastle.X509.X509Certificate>();
String alias = "";
foreach (string al in store.Aliases)
if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate)
{
alias = al;
break;
}
AsymmetricKeyEntry pk = store.GetKey(alias);
foreach (X509CertificateEntry c in store.GetCertificateChain(alias))
chain.Add(c.Certificate);
RsaPrivateCrtKeyParameters parameters = pk.Key as RsaPrivateCrtKeyParameters;
IExternalSignature pks = new PrivateKeySignature(parameters, DigestAlgorithms.SHA256);
pks.Sign(Encoding.ASCII.GetBytes("Robert Dejournett"));
MakeSignature.SignDetached(appearance, pks, chain, null, null, null, 0, CryptoStandard.CMS);
stamper.Close();
}
catch (Exception ex)
{
Console.WriteLine("GMA: " + ex.Message);
}
finally
{
if (reader != null)
reader.Close();
if (stamper != null)
stamper.Close();
if (os != null)
os.Close();
}
}
编辑-这就是我的意思
尝试将证书添加到受信任的证书列表应能解决此问题 我对受信任站点颁发的证书没有问题,但如果证书来源未知,则会发生此问题。
最后,我使用您的代码创建了一个应用程序,并在将证书添加到可信站点后自动解决了这个问题。您无法看到签名图像吗?@Rex否,图像正常。联系人、位置等附近有一个未填充的“签名人”字段。我不知道如何填充该字段。看到新的屏幕截图。你能分享有问题的PDF吗?谢谢,这样你就可以在GenerateCertToFile中看到上面生成证书的代码-我想在“签名人”中显示的文本放在哪里。我查看了X509V3CertificateGenerator对象,没有看到明显的斑点。我正在填充SubjectDN和IssuerDN,在“signed by”上我看不到它们。我也按照您的建议将证书导入到证书存储中(这并没有解决问题)。我没有修改您的代码并向我显示由“mdanderson.org”签名的证书,该证书是SubjectDN(但由于证书不是受信任的证书,所以没有第一次显示)。稍后,将通过代码生成的证书添加到受信任的证书,然后重新打开生成的PDF解决了我的问题。我已在此处上载了我的解决方案,我使用的是Acrobat reader Dc 2017版本。在Acrobat reader->中从签名属性-->显示签名者的证书->信任选项卡->添加到中打开PDF可信证书。我们需要这样做的原因是为了信任站点,因为证书是在运行时生成的,这是未知的。我尝试在Acrobat和Nitro中打开相同的PDF,但Acrobat shows的签名是where as Nitro,而不是
static private void GenerateCertToFile(string certFileName, string password)
{
RsaKeyPairGenerator kpGenerator = new RsaKeyPairGenerator();
kpGenerator.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
// Create a keypair
AsymmetricCipherKeyPair kp = kpGenerator.GenerateKeyPair();
// Certificate Generator
X509V3CertificateGenerator cGenerator = new X509V3CertificateGenerator();
cGenerator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
cGenerator.SetSubjectDN(new X509Name("CN=" + "mdanderson.org"));
cGenerator.SetIssuerDN(new X509Name("CN=" + "ADCL"));
cGenerator.SetNotBefore(DateTime.Now);
cGenerator.SetNotAfter(DateTime.Now.Add(new TimeSpan(365, 0, 0, 0))); // Expire in 1 year
//cGenerator.SetSignatureAlgorithm(HashType.SHA1withDSA.ToString()); // See the Appendix Below for info on the hash types supported by Bouncy Castle C#
cGenerator.SetSignatureAlgorithm("SHA256WithRSA");
cGenerator.SetPublicKey(kp.Public); // Only the public key should be used here!
Org.BouncyCastle.X509.X509Certificate cert = cGenerator.Generate(kp.Private); // Create a self-signed cert
// Create the PKCS12 store
Pkcs12Store store = new Pkcs12StoreBuilder().Build();
// Add a Certificate entry
X509CertificateEntry certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry(cert.SubjectDN.ToString(), certEntry); // use DN as the Alias.
// Add a key entry
AsymmetricKeyEntry keyEntry = new AsymmetricKeyEntry(kp.Private);
store.SetKeyEntry(cert.SubjectDN.ToString() + "_key", keyEntry, new X509CertificateEntry[] { certEntry }); // Note that we only have 1 cert in the 'chain'
// Save to the file system
using (var filestream = new FileStream(certFileName, FileMode.Create, FileAccess.ReadWrite))
{
store.Save(filestream, password.ToCharArray(), new SecureRandom());
}
}