Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用iText锁定pdf_Java_Pdf_Itext7 - Fatal编程技术网

Java 使用iText锁定pdf

Java 使用iText锁定pdf,java,pdf,itext7,Java,Pdf,Itext7,我最近尝试迁移到iText7,但我有一些问题。我已经有一个PDF,我正在尝试锁定和限制对此PDF的权限。我对itext5使用了相同的方法,但结果不一样。更准确地说: 我曾经 PdfWriter writer = new PdfWriter(fos, new WriterProperties() .setPublicKeyEncryption(chain, new int[EncryptionConstants.ALLOW_DEGRADED_PRINTING],

我最近尝试迁移到iText7,但我有一些问题。我已经有一个PDF,我正在尝试锁定和限制对此PDF的权限。我对itext5使用了相同的方法,但结果不一样。更准确地说:

  • 我曾经

    PdfWriter writer = new PdfWriter(fos, new WriterProperties()
            .setPublicKeyEncryption(chain,
            new int[EncryptionConstants.ALLOW_DEGRADED_PRINTING],
            EncryptionConstants.ENCRYPTION_AES_256));
    
  • 但是什么也没发生,然后我试了一下

    二,

    什么也没发生。你知道这件事吗

    方法的完整代码:

     public void signPDF(InputStream inputStream, HttpServletResponse response) {
            LOG.debug("Inside signPDF...");
            Security.addProvider(new BouncyCastleProvider());
            try(OutputStream os = response.getOutputStream();
                PdfReader reader = new PdfReader(inputStream);
                PdfWriter writer = new PdfWriter(os, new WriterProperties().setStandardEncryption(null, "test".getBytes(), EncryptionConstants.ALLOW_PRINTING,
                        EncryptionConstants.ENCRYPTION_AES_128 | EncryptionConstants.DO_NOT_ENCRYPT_METADATA))) {
                KeyStore ks = KeyStore.getInstance("pkcs12");
                ks.load(new FileInputStream(p12Path), keystorePassword.toCharArray());
                String alias = ks.aliases().nextElement();
                PrivateKey pk = (PrivateKey) ks.getKey(alias, keystorePassword.toCharArray());
                Certificate[] chain = ks.getCertificateChain(alias);
                BouncyCastleProvider provider = new BouncyCastleProvider();
                ITSAClient tsc = new TSAClientBouncyCastle(tsaClient, "", "");
                PdfSigner signer = new PdfSigner(reader, writer.getOutputStream(), true);
                PdfSignatureAppearance appearance = signer.getSignatureAppearance()
                        .setReason("Sign")
                        .setLocation("Test")
                        .setReuseAppearance(false);
                signer.setFieldName("sig");
                IExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, provider.getName());
                IExternalDigest digest = new BouncyCastleDigest();
                System.out.println(signer.getDocument().getNumberOfPages());
                addWatermark(appearance,signer);
                signer.signDetached(digest, pks, chain, null, null, tsc, 0, PdfSigner.CryptoStandard.CMS);
    
            } catch (Exception e) {
                LOG.error("Error while writing to outputstream",e);
            }
        }
    

    现在它已签名,有水印,但未锁定(即复制内容)

    iText 7中的签名和加密目前分两步完成,第一步对文件进行加密,第二步对加密文件进行签名,保持加密完整

    在您的尝试中,您创建了带有加密信息的
    PdfWriter
    ,以及带有签名信息的
    PdfSigner
    。由于任何
    pdf文档都没有使用您的
    PdfWriter
    ,因此加密信息会丢失,只会进行签名

    要同时加密和签名,只需先加密PDF,例如使用

    void sign(InputStream original, OutputStream result, String name, CryptoStandard subfilter,
            int certificationLevel, boolean isAppendMode, byte[] password) throws IOException, GeneralSecurityException {
        String reason = "Just another illusionary reason";
        String location = "Right around the corner";
        boolean setReuseAppearance = false;
        String digestAlgorithm = "SHA512";
        ITSAClient tsc = null;
    
        PdfReader reader = new PdfReader(original, new ReaderProperties().setPassword(password));
        PdfSigner signer = new PdfSigner(reader, result, isAppendMode);
    
        signer.setCertificationLevel(certificationLevel);
    
        // Creating the appearance
        signer.getSignatureAppearance()
              .setReason(reason)
              .setLocation(location)
              .setReuseAppearance(setReuseAppearance);
    
        signer.setFieldName(name);
    
        // Creating the signature
        IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, BouncyCastleProvider.PROVIDER_NAME);
        signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, tsc, 0, subfilter);
    }
    
    void encrypt(InputStream源、OutputStream目标、字节[]密码)引发IOException{
    PdfReader reader=新PdfReader(源);
    PdfWriter writer=新PdfWriter(目标,新WriterProperties()。设置标准加密(null,密码,
    EncryptionConstants.ALLOW_PRINTING,EncryptionConstants.ENCRYPTION_AES_128 | EncryptionConstants.DO_NOT_ENCRYPT_METADATA));
    新PDF文档(读写器).close();
    }
    
    (一种方法)

    然后在加密的PDF上签名,例如使用

    void sign(InputStream original, OutputStream result, String name, CryptoStandard subfilter,
            int certificationLevel, boolean isAppendMode, byte[] password) throws IOException, GeneralSecurityException {
        String reason = "Just another illusionary reason";
        String location = "Right around the corner";
        boolean setReuseAppearance = false;
        String digestAlgorithm = "SHA512";
        ITSAClient tsc = null;
    
        PdfReader reader = new PdfReader(original, new ReaderProperties().setPassword(password));
        PdfSigner signer = new PdfSigner(reader, result, isAppendMode);
    
        signer.setCertificationLevel(certificationLevel);
    
        // Creating the appearance
        signer.getSignatureAppearance()
              .setReason(reason)
              .setLocation(location)
              .setReuseAppearance(setReuseAppearance);
    
        signer.setFieldName(name);
    
        // Creating the signature
        IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, BouncyCastleProvider.PROVIDER_NAME);
        signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, tsc, 0, subfilter);
    }
    
    (一种方法)

    与代码中的
    pk
    chain
    类似

    然后将这些方法结合起来,例如

    try (   InputStream resourceStream = ...;
            OutputStream encryptedResult = new FileOutputStream(encryptedFile)  ) {
        encrypt(resourceStream, encryptedResult, password);
    }
    
    try (   InputStream encryptedSource = new FileInputStream(encryptedFile);
            OutputStream signedResult = new FileOutputStream(signedFile)) {
        sign(encryptedSource, signedResult, "Signature", CryptoStandard.CADES, 0, false, password);
    }
    
    (测试
    测试加密和签名lefterisbab

    或者,如果要写入响应而不希望文件系统中存在中间文件,请执行以下操作:

    byte[] encrypted = null;
    
    try (   InputStream resourceStream = ...;
            OutputStream encryptedResult = new ByteArrayOutputStream()  ) {
        encrypt(resourceStream, encryptedResult, password);
        encrypted = encryptedResult.toByteArray();
    }
    
    try (   InputStream encryptedSource = new ByteArrayInputStream(encrypted);
            OutputStream signedResult = response.getOutputStream()   ) {
        sign(encryptedSource, signedResult, "Signature", CryptoStandard.CADES, 0, false, password);
    }
    

    iText 7中的签名和加密目前分为两个单独的步骤,第一步对文件进行加密,第二步对加密文件进行签名,保持加密完整

    在您的尝试中,您创建了带有加密信息的
    PdfWriter
    ,以及带有签名信息的
    PdfSigner
    。由于任何
    pdf文档都没有使用您的
    PdfWriter
    ,因此加密信息会丢失,只会进行签名

    要同时加密和签名,只需先加密PDF,例如使用

    void sign(InputStream original, OutputStream result, String name, CryptoStandard subfilter,
            int certificationLevel, boolean isAppendMode, byte[] password) throws IOException, GeneralSecurityException {
        String reason = "Just another illusionary reason";
        String location = "Right around the corner";
        boolean setReuseAppearance = false;
        String digestAlgorithm = "SHA512";
        ITSAClient tsc = null;
    
        PdfReader reader = new PdfReader(original, new ReaderProperties().setPassword(password));
        PdfSigner signer = new PdfSigner(reader, result, isAppendMode);
    
        signer.setCertificationLevel(certificationLevel);
    
        // Creating the appearance
        signer.getSignatureAppearance()
              .setReason(reason)
              .setLocation(location)
              .setReuseAppearance(setReuseAppearance);
    
        signer.setFieldName(name);
    
        // Creating the signature
        IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, BouncyCastleProvider.PROVIDER_NAME);
        signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, tsc, 0, subfilter);
    }
    
    void encrypt(InputStream源、OutputStream目标、字节[]密码)引发IOException{
    PdfReader reader=新PdfReader(源);
    PdfWriter writer=新PdfWriter(目标,新WriterProperties()。设置标准加密(null,密码,
    EncryptionConstants.ALLOW_PRINTING,EncryptionConstants.ENCRYPTION_AES_128 | EncryptionConstants.DO_NOT_ENCRYPT_METADATA));
    新PDF文档(读写器).close();
    }
    
    (一种方法)

    然后在加密的PDF上签名,例如使用

    void sign(InputStream original, OutputStream result, String name, CryptoStandard subfilter,
            int certificationLevel, boolean isAppendMode, byte[] password) throws IOException, GeneralSecurityException {
        String reason = "Just another illusionary reason";
        String location = "Right around the corner";
        boolean setReuseAppearance = false;
        String digestAlgorithm = "SHA512";
        ITSAClient tsc = null;
    
        PdfReader reader = new PdfReader(original, new ReaderProperties().setPassword(password));
        PdfSigner signer = new PdfSigner(reader, result, isAppendMode);
    
        signer.setCertificationLevel(certificationLevel);
    
        // Creating the appearance
        signer.getSignatureAppearance()
              .setReason(reason)
              .setLocation(location)
              .setReuseAppearance(setReuseAppearance);
    
        signer.setFieldName(name);
    
        // Creating the signature
        IExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, BouncyCastleProvider.PROVIDER_NAME);
        signer.signDetached(new BouncyCastleDigest(), pks, chain, null, null, tsc, 0, subfilter);
    }
    
    (一种方法)

    与代码中的
    pk
    chain
    类似

    然后将这些方法结合起来,例如

    try (   InputStream resourceStream = ...;
            OutputStream encryptedResult = new FileOutputStream(encryptedFile)  ) {
        encrypt(resourceStream, encryptedResult, password);
    }
    
    try (   InputStream encryptedSource = new FileInputStream(encryptedFile);
            OutputStream signedResult = new FileOutputStream(signedFile)) {
        sign(encryptedSource, signedResult, "Signature", CryptoStandard.CADES, 0, false, password);
    }
    
    (测试
    测试加密和签名lefterisbab

    或者,如果要写入响应而不希望文件系统中存在中间文件,请执行以下操作:

    byte[] encrypted = null;
    
    try (   InputStream resourceStream = ...;
            OutputStream encryptedResult = new ByteArrayOutputStream()  ) {
        encrypt(resourceStream, encryptedResult, password);
        encrypted = encryptedResult.toByteArray();
    }
    
    try (   InputStream encryptedSource = new ByteArrayInputStream(encrypted);
            OutputStream signedResult = response.getOutputStream()   ) {
        sign(encryptedSource, signedResult, "Signature", CryptoStandard.CADES, 0, false, password);
    }
    

    请向我们展示代码的完整版本。您使用的编写器创建逻辑是正确的,并且应该生成密码加密的文档。啊,因此您希望同时进行签名和加密,而您将这两个任务组合在一起的方式是错误的,您的带有加密信息的
    PdfWriter
    根本不被使用。稍后我将尝试更正代码。谢谢@mkl,我为5.x版编写了代码,现在我将其更改为7.x版,我发现这有点棘手。请注意,PdfEncryptor.encrypt()关闭了流…请向我们展示代码的完整版本。您使用的编写器创建逻辑是正确的,并且应该生成密码加密的文档。啊,因此您希望同时进行签名和加密,而您将这两个任务组合在一起的方式是错误的,您的带有加密信息的
    PdfWriter
    根本不被使用。稍后我将尝试更正代码。谢谢@mkl,我为5.x版编写了代码,现在我将其更改为7.x版,我发现这有点棘手。请注意,PdfEncryptor.encrypt()关闭了流。。。。