2017-01-19 153 views
1

タイムスタンプをサードパーティのタイムサーバーからファイルに追加したいと思います。 pdfがacrobatや他のpdfビューアで開いているときに、署名カードなどのタイムスタンプに関する情報を見たいと思っています。また、タイムスタンプ付きのpdfの画像やテキストとしてタイムスタンプを視覚的に視覚化したい。pdfboxとTimeStampTokenでタイムスタンプを追加するには

私は、タイムサーバからトークンを取得:

import org.bouncycastle.tsp.TimeStampResponse; 
import org.bouncycastle.tsp.TimeStampToken; 

... 

public TimeStampToken getTimeStampToken(){ 

    ... 

    return response.getTimeStampToken(); 
} 

PDFボックスを使用してPDFにタイムスタンプを追加するために今どのように?

import org.apache.pdfbox.pdmodel.PDDocument; 
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; 

... 

public static void addTimeStamp(final File pdfFile, final File signedPdfFile, TimeStampToken token) { 

    try (
     FileInputStream fis1 = new FileInputStream(pdfFile); 
     FileOutputStream fos = new FileOutputStream(signedPdfFile); 
     FileInputStream fis = new FileInputStream(signedPdfFile); 
     PDDocument doc = PDDocument.load(pdfFile)) { 
     int readCount; 
     final byte[] buffer = new byte[8 * 1024]; 
     while ((readCount = fis1.read(buffer)) != -1) { 
      fos.write(buffer, 0, readCount); 
     } 

     final PDSignature signature = new PDSignature(); 
     signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); 
     signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); 
     signature.setName("NAME"); 
     signature.setLocation("LOCATION"); 
     signature.setReason("REASON"); 
     signature.setSignDate(Calendar.getInstance()); 

     doc.addSignature(signature); 
     doc.saveIncremental(fos); 
    } catch (final Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

署名サンプルコードは、グラフィカル「を除いて、すでにこれを持っていませんpdfの画像またはテキストとして表示されます。あなたはそれを見ましたか? –

答えて

1

あなただけのタイムスタンプではなく、署名タイムスタンプ付きの署名を言及したように、私はあなたが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")); 

タイムスタンプにタイプを設定します。

0

私は、キーストアの証明書とキーなしでPDFにタイムスタンプを追加したいと、それは次のようになります。

public static void signWithTimeStampToken() throws InvalidPasswordException, NoSuchAlgorithmException, IOException, TSPException { 
    final File inFile = new File("test.pdf"); 
    final File outFile = new File("test_signed.pdf"); 
    final MessageDigest digest = MessageDigest.getInstance("SHA-1"); 
    final TSAClient tsaClient = new TSAClient(new URL("your service"), null, null, digest); 
    PdfTimeStampUtils.signPdf(inFile, outFile, tsaClient); 
} 

private static void signPdf(final File inFile, final File outFile, final TSAClient tsaClient) throws InvalidPasswordException, IOException, NoSuchAlgorithmException, 
     TSPException { 
    final PDSignature signature = new PDSignature(); 
    signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); 
    signature.setSubFilter(COSName.getPDFName("ETSI.RFC3161")); 
    signature.setSignDate(Calendar.getInstance()); 
    final PDDocument pdf = PDDocument.load(inFile); 

    final TimestampSignatureImpl sig = new TimestampSignatureImpl(tsaClient); 
    pdf.addSignature(signature, sig); 
    pdf.saveIncremental(new FileOutputStream(outFile)); 
    pdf.close(); 
} 

私はAcrobatで私に署名したPDFファイルを開くと、私はpdfbox例からTSAClient

をtsaclientを使用しています署名で見ることができます:

enter image description here

+0

あなたの質問では、*タイムスタンプを視覚的に視覚化したいと言っていました。これは通常、署名付きパネルのエントリではなく、コンテンツ内の視覚化を意味します。私はあなたを誤解していたのでしょうか? – mkl

+0

私が何を意味するかは、添付画像のように署名を見ることなく、署名と署名なしを区別するために何か(カスタム画像やテキスト)を追加する能力を持つことです。しかし、それは追加的(私は好奇心が強い)であり、私の答えはそれを全く含んでいません。私はタイムスタンプを追加する方法を考え出したので、それを配置しました。 –

関連する問題