10

Windows証明書ストアにある証明書を使用してPDFドキュメントに署名する必要があります。私はそれを理解しようと一日中掘り下げていました、そして私はとても近くにいますが、遠く離れています。

不足しているのはこれだけです:PDFファイルに署名するためのIExternalSignatureオブジェクトを取得するにはどうすればよいですか?

Rahul Singlaは、新しいiText 5.3.0 APIを使用してPDFドキュメントに署名する方法の美しい例を作成しました。ただし、PCのどこかにある.pfxファイルにアクセスできる場合に限ります。

Windows Cert Storeからの証明書を使用して署名することについての前の質問がありますが、それはSetCryptoまだ存在するAPIのバージョンを使用しており、署名は明らかにオプションでした。iText 5.3.0では、APIが変更されており、SetCryptoもはや問題ではありません。

これが私がこれまでに持っているものです(これはネット上でこれを行う方法の最も完全で最新のバージョンである可能性があるため、後世のためにコメントが追加されています):

using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using BcX509 = Org.BouncyCastle.X509;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Crypto;
using DotNetUtils = Org.BouncyCastle.Security.DotNetUtilities;

...

// Set up the PDF IO
PdfReader reader = new PdfReader(@"some\dir\SomeTemplate.pdf");
PdfStamper stamper = PdfStamper.CreateSignature(reader,
    new FileStream(@"some\dir\SignedPdf.pdf", FileMode.Create), '\0');
PdfSignatureAppearance sap = stamper.SignatureAppearance;

sap.Reason = "For no apparent raisin";
sap.Location = "...";

// Acquire certificate chain
var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);

X509CertificateCollection certCollection =
    certStore.Certificates.Find(X509FindType.FindBySubjectName,
    "My.Cert.Subject", true);
X509Certificate cert = certCollection[0];
// iTextSharp needs this cert as a BouncyCastle X509 object; this converts it.
BcX509.X509Certificate bcCert = DotNetUtils.FromX509Certificate(cert);
var chain = new List<BcX509.X509Certificate> { bcCert };
certStore.Close();

// Ok, that's the certificate chain done. Now how do I get the PKS?
IExternalSignature signature = null; /* ??? */

// Sign the PDF file and finish up.
MakeSignature.SignDetached(sap, signature, chain, // the important stuff
    null, null, null, 0, CryptoStandard.CMS);
stamper.Close();

ご覧のとおり、私は署名以外のすべてを持っていますが、それをどのように取得するかについて困惑しています。

4

3 に答える 3

4
public byte[] SignPdf(byte[] pdf)
{
    using (MemoryStream output = new MemoryStream())
    {
        //get certificate from path
        X509Certificate2 cert1 = new X509Certificate2(@"C:\temp\certtemp.pfx", "12345", X509KeyStorageFlags.Exportable);
        //get private key to sign pdf
        var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(cert1.PrivateKey).Private;
        // convert the type to be used at .SetCrypt(); 
        Org.BouncyCastle.X509.X509Certificate bcCert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(cert1);
        // get the pdf u want to sign
        PdfReader pdfReader = new PdfReader(pdf);

        PdfStamper stamper = PdfStamper.CreateSignature(pdfReader, output, '\0');
        PdfSignatureAppearance pdfSignatureAppearance = stamper.SignatureAppearance;
        //.SetCrypt(); sign the pdf
        pdfSignatureAppearance.SetCrypto(pk, new Org.BouncyCastle.X509.X509Certificate[] { bcCert }, null, PdfSignatureAppearance.WINCER_SIGNED);

        pdfSignatureAppearance.Reason = "Este documento está assinado digitalmente pelo Estado Portugues";
        pdfSignatureAppearance.Location = " Lisboa, Portugal";
        pdfSignatureAppearance.SignDate = DateTime.Now;

        stamper.Close();

        return output.ToArray();
    }
} 

このコードを使用してPDFを取得し、署名済みbyte[]のPDFを再度返します。byte[]

それはiTextSharp-LGPLです。

于 2018-02-19T13:54:48.293 に答える
3
X509Certificate cert = certCollection[0]; // Your code
X509Certificate2 signatureCert = new X509Certificate2(cert);

var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(signatureCert.PrivateKey).Private;

上記のように取得できるpkがある場合は、次のようにIExternalSignatureを作成します。

IExternalSignature es = new PrivateKeySignature(pk, "SHA-256");

次の使用記事もあります。

于 2013-02-21T10:41:49.933 に答える
0

PDFとデジタル署名の本をダウンロードしてください。Windows証明書ストアを使用して署名する方法のJavaの例は、第3章にあります。ご覧のとおり、Windows-MYキーストアが必要です。

次に、これらの例のC#ポートを公開したリポジトリに移動します。C3_11_SignWithToken.csを探します。

X509Store x509Store = new X509Store("My");
x509Store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificates = x509Store.Certificates;
IList<X509Certificate> chain = new List<X509Certificate>();
X509Certificate2 pk = null;
if (certificates.Count > 0) {
    X509Certificate2Enumerator certificatesEn = certificates.GetEnumerator();
    certificatesEn.MoveNext();
    pk = certificatesEn.Current;
    X509Chain x509chain = new X509Chain();
    x509chain.Build(pk);
    foreach (X509ChainElement x509ChainElement in x509chain.ChainElements) {
        chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate));
    }
}
x509Store.Close();

私が正しく理解しchainpkいて、あなたが探していた変数である場合;

于 2013-02-21T11:27:44.970 に答える