2017-11-27 15 views
0

クライアント/サーバpdf署名に関する私の研究の一部として、私はpdf遅延署名の例をテストしました。残念なことに私の得られたpdf、すなわち、マージされた空の署名pdfとハッシュ値の出力は、無効な署名を示す。Itext pdf遅延署名が無効な署名を含むpdfになる

私のコードスニペットは、

class MyExternalSignatureContainer implements ExternalSignatureContainer { 
    protected byte[] sig; 
    protected Certificate[] chain; 
    public MyExternalSignatureContainer(byte[] sig,Certificate[] chain) { 
     this.sig = sig; 
     this.chain=chain; 
    } 
    public byte[] sign(InputStream is)throws GeneralSecurityException { 

     return sig; 
    } 


public byte[] emptySignature_hash(String src, String dest, String fieldname, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException { 
     PdfReader reader = new PdfReader(src); 
     FileOutputStream os = new FileOutputStream(dest); 
     PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); 
     PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); 
     appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, fieldname); 
     appearance.setCertificate(chain[0]); 
     ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); 
     MakeSignature.signExternalContainer(appearance, external, 8192); 
     InputStream inp = appearance.getRangeStream(); 
     BouncyCastleDigest digest = new BouncyCastleDigest(); 
     PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false); 
     byte[] hash = DigestAlgorithms.digest(inp, digest.getMessageDigest("SHA256")); 
     Calendar cal = Calendar.getInstance(); 
     cal1=cal; 
     System.out.println(cal); 
     byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS); 

     return(sh); 
    } 

public byte[] signed_hash(byte[] hash, PrivateKey pk, Certificate[] chain)throws GeneralSecurityException{ 
     PrivateKeySignature signature = new PrivateKeySignature(pk, "SHA256", "SunPKCS11-eToken"); 
     byte[] extSignature = signature.sign(hash); 
     //return extSignature; 
     BouncyCastleDigest digest = new BouncyCastleDigest(); 
     Calendar cal = Calendar.getInstance(); 
     String hashAlgorithm = signature.getHashAlgorithm(); 
     System.out.println(hashAlgorithm); 
     PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false); 
     sgn.setExternalDigest(extSignature, null, signature.getEncryptionAlgorithm()); 
    return sgn.getEncodedPKCS7(hash, cal1, null, null, null, CryptoStandard.CMS); 

     } 

public void createSignature(String src, String dest, String fieldname,byte[] hash, PrivateKey pk, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException { 

    PdfReader reader = new PdfReader(src); 
    FileOutputStream os = new FileOutputStream(dest); 
    ExternalSignatureContainer external = new MyExternalSignatureContainer(hash,chain); 
    MakeSignature.signDeferred(reader, fieldname, os, external); 
} 

public static void main(String[] args) throws IOException, GeneralSecurityException, DocumentException { 

byte[] hh = app.emptySignature_hash(SRC, TEMP, "sig1", chain); 
       byte[] hh_sign = (app.signed_hash(hh, pk, chain)); 
       app.createSignature(TEMP, DEST1, "sig1",hh_sign, pk, chain); 

} 

何かが間違っていた次の。私は理解できませんでした。同じチュートリアルをたくさん検索しました。あなたはそれのためにMakeSignature.signExternalContainerを実行した後PdfSignatureAppearance appearanceを使用すると、私は

+0

あなたは非常に古いiTextバージョンを使用しています: 'PdfPKCS7'メソッドの' getAuthenticatedAttributeBytes'と 'getEncodedPKCS7'には' Calendar'パラメータがありませんでした。... – mkl

答えて

1

あなたのアーキテクチャに署名するためpkcss11のUSBトークンを使用しています

は限り間違っています。 signExternalContainerおよびsignDetachedの両方のオーバーロードは、PdfStamper,PdfSignatureAppearanceおよびPdfReaderのインスタンスを閉じます。

したがって、あなたはemptySignature_hash

MakeSignature.signExternalContainer(appearance, external, 8192); 
    InputStream inp = appearance.getRangeStream(); 

あなたの方法で次の手順を実行したときに、あなたのinpは必ずしも賢明なものを含めることはできません。

代わりにあなたがバイトにアクセスする必要がありますが、あなたのexternalオブジェクトに署名する範囲は、そのsignメソッドのパラメータとして取得します。そのメソッドにハッシュ計算を単純にリファクタリングし、計算されたハッシュをそのコンテナのメンバーに格納してemptySignature_hashに取得します。

あなたの署名コードの例を共有していないので、私はあなたの署名に他の問題があるかどうかを判断しようとすることはできません。

+0

以下のメソッドを変更して動作しています –

0

私の間違いでした。 私はemptySignature_hashメソッドとsigned_hashを次のように変更しました。

emptySignature_hashメソッドの戻り値は

public byte[] emptySignature_hash(String src, String dest, String fieldname, Certificate[] chain) throws IOException, DocumentException, GeneralSecurityException { 
     PdfReader reader = new PdfReader(src); 
     FileOutputStream os = new FileOutputStream(dest); 
     PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); 
     PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); 
     appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, fieldname); 
     appearance.setCertificate(chain[0]); 
     ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); 
     MakeSignature.signExternalContainer(appearance, external, 8192); 



     InputStream inp = appearance.getRangeStream(); 

     BouncyCastleDigest digest = new BouncyCastleDigest(); 


     byte[] hash = DigestAlgorithms.digest(inp, digest.getMessageDigest("SHA256")); 
     return hash; 

    } 




public byte[] signed_hash(byte[] hash, PrivateKey pk, Certificate[] chain)throws GeneralSecurityException{ 
     PrivateKeySignature signature = new PrivateKeySignature(pk, "SHA256", "SunPKCS11-eToken"); 
     BouncyCastleDigest digest = new BouncyCastleDigest(); 
     Calendar cal = Calendar.getInstance(); 
     String hashAlgorithm = signature.getHashAlgorithm(); 
     System.out.println(hashAlgorithm); 
     PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, digest, false); 

     byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS); 
     byte[] extSignature = signature.sign(sh); 

     System.out.println(signature.getEncryptionAlgorithm()); 
     sgn.setExternalDigest(extSignature, null, signature.getEncryptionAlgorithm()); 
    return sgn.getEncodedPKCS7(hash, cal, null, null, null, CryptoStandard.CMS); 

     } 

iは、問題は、私はemptysignature_hash方法でハッシュのgetAuthenticatedAttributeBytesを返していました以前だったと思うauthenticatedbytesないダイジェスト。

signed_hash()メソッドでは、authenticatedattributebytesを sgn.getEncodedPKCS7に渡していました。