あなただけのタイムスタンプではなく、署名タイムスタンプ付きの署名を言及したように、私はあなたがPAdES LTVやPDF-2ごとに文書のタイムスタンプを意味すると仮定します。
PDFBoxの署名の例は、裸のデジタルタイムスタンプではなく、通常のデジタル署名を念頭に置いて実装されています。しかし、あなたはそれをかなり簡単に適応させることができます。 CreateVisibleSignatureおよび他の例は、署名がsign
が親クラスCreateSignatureBase
に実装SignatureInterface
方法に埋め込むバイト作成:
/**
* SignatureInterface implementation.
*
* This method will be called from inside of the pdfbox and create the PKCS #7 signature.
* The given InputStream contains the bytes that are given by the byte range.
*
* This method is for internal use only.
*
* Use your favorite cryptographic library to implement PKCS #7 signature creation.
*/
@Override
public byte[] sign(InputStream content) throws IOException
{
//TODO this method should be private
try
{
List<Certificate> certList = new ArrayList<Certificate>();
certList.add(certificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(certificate.getEncoded()));
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(privateKey);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(sha1Signer, new X509CertificateHolder(cert)));
gen.addCertificates(certs);
CMSProcessableInputStream msg = new CMSProcessableInputStream(content);
CMSSignedData signedData = gen.generate(msg, false);
if (tsaClient != null)
{
signedData = signTimeStamps(signedData);
}
return signedData.getEncoded();
}
catch (GeneralSecurityException e)
{
throw new IOException(e);
}
catch (CMSException e)
{
throw new IOException(e);
}
catch (TSPException e)
{
throw new IOException(e);
}
catch (OperatorCreationException e)
{
throw new IOException(e);
}
}
(CreateSignatureBase)
(BTW、私は強くTODO、コメントに反対します。 )
さらに、CreateVisibleSignature
は、署名のサブフィルタをsignPDF
に設定します。
/**
* Sign pdf file and create new file that ends with "_signed.pdf".
*
* @param inputFile The source pdf document file.
* @param signedFile The file to be signed.
* @param tsaClient optional TSA client
* @param signatureFieldName optional name of an existing (unsigned) signature field
* @throws IOException
*/
public void signPDF(File inputFile, File signedFile, TSAClient tsaClient, String signatureFieldName) throws IOException
{
[...]
PDSignature signature;
// sign a PDF with an existing empty signature, as created by the CreateEmptySignatureForm example.
signature = findExistingSignature(doc, signatureFieldName);
if (signature == null)
{
// create signature dictionary
signature = new PDSignature();
}
// default filter
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
// subfilter for basic and PAdES Part 2 signatures
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
[...]
}
PAdES文書のタイムスタンプを作成するには、単にCreateVisibleSignature
例のコピーを作成し、与えられたInputStream
にデータのタイムスタンプトークンを返す実装でSignatureInterface
方法sign
をオーバーライドし、行を置き換えることができます
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setSubFilter(new COSName("ETSI.RFC3161"));
とsignPDF
で
と行を追加します
signature.setType(new COSName("DocTimeStamp"));
タイムスタンプにタイプを設定します。
出典
2017-01-19 08:35:37
mkl
署名サンプルコードは、グラフィカル「を除いて、すでにこれを持っていませんpdfの画像またはテキストとして表示されます。あなたはそれを見ましたか? –