защо имам 1 Miscellaneus Change - ако добавя Document Security Store

Подписах документ. и искам да добавя DSS към моя документ.

        Security.addProvider(new BouncyCastleProvider());

        File signedDocument = new File("/signed.pdf");
        File out = new File("/signed_plus_dss");

        byte[] buffer = new byte[8 * 1024];
        FileInputStream fis = new FileInputStream(signedDocument);
        FileOutputStream fos = new FileOutputStream(out);

        int c;
        while ((c = fis.read(buffer)) != -1) {
            fos.write(buffer, 0, c);
        }
        fis.close();
        fis = new FileInputStream(out);

        // load document
        PDDocument doc = PDDocument.load(signedDocument);
        PDDocumentCatalog catalog = doc.getDocumentCatalog();
        COSDictionary catalogDictionary = catalog.getCOSDictionary();
        COSDictionary dssDictionary = new COSDictionary();

        /* ... I can add OCSP responses, and CRLS, and Certs here    
            in order to create document LTV, but now I don't need that. 
            I have another problem, not this... */


        /* if that's false, nothing happens */ 
        catalogDictionary.setNeedToBeUpdate(true);
        catalogDictionary.setItem(COSName.getPDFName("DSS"), dssDictionary);  

        /* ... if we add here Document level time stamp, everything is fine.
        signature will not be invalid with TSA. but it's invalid without TSA ... */  
        doc.saveIncremental(fis, fos);

това е. всичко е наред. когато видя PDF Structure има Document Security Store. но когато отворя PDF с adobe reader, подписът ми е невалиден, защото - „Документът е променен или повреден, след като е бил подписан.“ и „1 Разни промени“

но тук се случва нещо интересно - ако добавя Pades-LTV (DSS + TSA), всичко работи:

например, ако добавим тези кодове:

        URL tsaURL = new URL(TSAUrl);
        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); 
        signature.setSubFilter(COSName.getPDFName("ETSI.RFC3161"));
        signature.setSignDate(Calendar.getInstance());
        TimestampeInt signatureInt = new TimestampeInt(tsaURL, null, null);
        doc.addSignature(signature, signatureInterface);
        doc.saveIncremental(fis, fos);

според резултата документ ниво време пън работи добре. Но трябва да добавя и само DSS без TSA. как мога да разреша този проблем, какво мислите?

примерни документи: Първата проба е - подпис плюс само DSS. Втората проба е подпис плюс DSS плюс документ на ниво време


person grep    schedule 26.07.2013    source източник


Отговори (1)


Докато както в първоначално подписания документ, така и в документа с добавени DSS и Timestamp, речникът AcroForm е директен обект в Каталога, той е непряк обект в документа само с добавен DSS:

SIGN.pdf:

5 0 obj
<<
/Type /Catalog
/Pages 3 0 R
/AcroForm <<
/Fields [7 0 R]
/SigFlags 3
>>
>> 
endobj

SIGN+DSS.pdf:

5 0 obj
<<
/Type /Catalog
/Pages 3 0 R
/AcroForm 12 0 R
/DSS 13 0 R
>>
endobj
12 0 obj
<<
/Fields [7 0 R]
/SigFlags 3
>> 
endobj

SIGN+DSS+TSA.pdf:

5 0 obj
<<
/Type /Catalog
/Pages 3 0 R
/AcroForm <<
/Fields [7 0 R 12 0 R]
/SigFlags 3
>>
/DSS 13 0 R
>> 
endobj

Въпреки че това е еквивалентно за наличните документи, Adobe Reader може да бъде объркан от това.

Подправих вашия SIGN+DSS.pdf, за да има и речника AcroForm като директен обект в Каталога тук и Adobe Reader беше щастлив...

Разлика в коригираната версия SIGN+DSS.pdf

person mkl    schedule 26.07.2013
comment
mkl. винаги си страхотен! p.s с редактор използвате ли, за да видите два документа заедно в шестнадесетични стойности (за да видите разликите)? Имам само Araxis Merge. - person grep; 26.07.2013
comment
import java.util.Random;

public class RockPaperScissor {

    static String ret;

    public static void main(String args[]) {

        String computer = compChoice();
        winnerRet(args[0], computer);

    }

    public static void winnerRet(String user, String compGuess) {

        if (user.equals("R")) {
            if (!compGuess.equals("P")) {
                if (!compGuess.equals("R")) {
                    ret = "Win";
                } else {
                    ret = "Draw";
                }
            } else {
                ret = "Lose";
            }
        } else if (user.equals("S")) {
            if (!compGuess.equals("R")) {
                if (!compGuess.equals("S")) {
                    ret = "Win";
                } else {
                    ret = "Draw";
                }
            } else {
                ret = "Lose";
            }
        } else if (user.equals("P")) {
            if (!compGuess.equals("S")) {
                if (!compGuess.equals("P")) {
                    ret = "Win";
                } else {
                    ret = "Draw";
                }
            } else {
                ret = "Lose";
            }
        }

        System.out.println(compGuess);
        System.out.println(ret);

    }

    public static String compChoice() {

        String compGuess;

        Random random = new Random();
        int compNum = random.nextInt(3) + 1;

        if (compNum == 1) {
            compGuess = "R";
        } else if (compNum == 2) {
            compGuess = "S";
        } else {
            compGuess = "P";
        }

        return compGuess;

    }

}

Е, аз бързо създадох игра камък-ножица-хартия без частта за броене сам въз основа на вашия код. Изглежда, че работи. Е, предполагам, че можете да погледнете моя код и да редактирате своя въз основа на него. Мисля, че проблемът беше, че сравнявахте символи с ==. Използвах струни, така че можете да ги размените.

- person mkl; 26.07.2013