提示:PDF加密是指对PDF文档进行加密保护,以防止未经授权的访问或篡改。通过对PDF文件进行加密,只有授权的人才能查看、编辑或打印文件,从而保护敏感信息和保护文档的完整性。本篇博客详细介绍了pdf加密的实现过程。
前言
在某些业务场景下,需要用到将word转换成pdf格式的文件,然后将pdf进行加密处理,在基于这一原理的情况下写了这篇博客来实现pdf加密的功能,并将加密的密码输出在日志中。
提示:以下是本篇文章正文内容,下面案例可供参考
一、在pom中引入jar依赖
引入工具类所需要的依赖包 并刷新maven
<!-- pdf转图片-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.12</version>
</dependency>
<!-- 处理文件-->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
二、编写pdf加密工具类 加密成功后返回ture
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
/**
* pdf加密工具类 加密成功后返回ture
*/
public class PdfEncryptionUtil {
private static final Logger log = LoggerFactory.getLogger(PdfEncryptionUtil.class);
private static void toPDF(String fileUrl) {
File file = new File(fileUrl);
try (PDDocument document = PDDocument.load(file);
FileOutputStream fos = new FileOutputStream(fileUrl)
) {
PDFRenderer renderer = new PDFRenderer(document);
Document doc = new Document(null, 0, 0, 0, 0);
PdfWriter.getInstance(doc, fos);
String imagePath = null;
for (int i = 0; i < document.getNumberOfPages(); ++i) {
FileOutputStream fos22 = null;
ByteArrayOutputStream out = null;
try {
imagePath = file.getPath() + UUID.randomUUID() + ".png";
File imageFile = new File(imagePath);
BufferedImage bufferedImage = renderer.renderImageWithDPI(i, 200);
out = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", out);
byte[] m = out.toByteArray();
fos22 = new FileOutputStream(imageFile);
fos22.write(m, 0, m.length);
doc.setPageSize(new Rectangle(bufferedImage.getWidth(), bufferedImage.getHeight()));
doc.open();
doc.add(Image.getInstance(imagePath));
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("生成纯图pdf错误");
} finally {
try {
if (fos22 != null) {
fos22.close();
}
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("流关闭错误!");
}
// 删除生成得图片 不在这里删除会删除不掉图片得
new File(imagePath).delete();
}
}
doc.close();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("读取初始pdf错误");
}
}
private static String getUUID() throws InterruptedException {
CountDownLatch count = new CountDownLatch(12);
StringBuffer sbd = new StringBuffer();
for (int i = 0; i < 4; i++) {
Thread thread = new Thread(() -> {
char ran1 = (char) (Math.random() * (90 - 65 + 1) + 65);
sbd.append(ran1);
count.countDown();
});
Thread thread1 = new Thread(() -> {
char ran2 = (char) (Math.random() * (122 - 97 + 1) + 97);
sbd.append(ran2);
count.countDown();
});
Thread thread2 = new Thread(() -> {
sbd.append(new Random().nextInt(9));
count.countDown();
});
thread.start();
thread1.start();
thread2.start();
}
try {
count.await();
} catch (Exception e) {
throw new InterruptedException("线程异常");
}
return sbd.substring(0, 10);
}
public static boolean toEncryption(String files) {
//创建一个在内存中表示pdf的类
PDDocument document = null;
try {
//加载现有的PDF文档s
File file = new File(files);
//实例化PDDocument
document = PDDocument.load(file);
//创建访问权限对象,实例化AccessPermission类
AccessPermission accessPermission = new AccessPermission();
//插入/旋转/删除页面
accessPermission.setCanAssembleDocument(false);
//从文档提取内容
accessPermission.setCanExtractContent(false);
//从文档中提取内容以实现可访问性。
accessPermission.setCanExtractForAccessibility(false);
//修改文档
accessPermission.setCanModify(false);
//打印
accessPermission.setCanPrint(true);
//填写交互表单字段(包括签名字段)
accessPermission.setCanFillInForm(false);
//设置用户是否可以添加或修改文本注释和填写交互表单字段,如果canModify()返回true,则创建或修改交互表单字段(包括签名字段)。
// 注意,如果canFillInForm()返回true,即使这里的参数为false,仍然可以填写交互表单(包括签名字段)。
accessPermission.setCanModifyAnnotations(false);
//以降级的格式打印文档
accessPermission.setCanPrintDegraded(false);
String uuid = getUUID();
log.info(file.getName() + "---" + uuid);
//通过传递所有者密码,用户密码和AccessPermission对象来实例化StandardProtectionPolicy类,第一个密码为执行上面八项操作需要的密码,第二个为打开文件需要的密码
StandardProtectionPolicy spp = new StandardProtectionPolicy(uuid, "", accessPermission);
//设置用于加密文档数据的密钥的长度(以位为单位)。默认值为40位
spp.setEncryptionKeyLength(128);
//加密文档
document.protect(spp);
//保存文档
document.save(files);
return true;
} catch (IOException | InterruptedException | RuntimeException e) {
e.printStackTrace();
return false;
} finally {
//关闭文件
if (document != null) {
try {
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 调用这里进行加密
*
* @param files
* @return
*/
public static boolean toDo(String files) {
toPDF(files);
// 加密
return toEncryption(files);
}
}
三、编写main方法进行测试加密pdf
public static void main(String[] args) {
// pdf加密
toDo("C:\\Users\\user\\Desktop\\123456789\\123456123\\123456123.pdf");
}
总结
以上就是PFD加密的整个过程,在某些业务场景下,需要用到将word转换成pdf格式的文件,然后将pdf进行加密处理,在基于这一原理的情况下写了这篇博客来实现pdf加密的功能,并将加密的密码输出在日志中。所以写下了这篇博客巩固一下盖功能点使用的方法,以及下次遇到相同的需求能够快速开发出来。