1 pdf转图片乱码问题
pdf是正常的,但是由pdf转成的图片,只要是中文,却是一堆框框,像这个问题,应该就是centos缺少字符集导致的
执行命令fc-list :lang=zh
,可以看到正常的如下:
而有问题的机器,则显示没有安装
依据上面的推论,执行
# 文泉驿微米黑字体
yum install -y wqy-microhei-fonts
执行完成后可以看到
那么其他的字符集,仿照写一些命令,执行的结果就跟之前的一木一样了。这样问题就解决了。
yum install -y fontconfig mkfontscale
yum install -y wqy-microhei-fonts
yum install -y wqy-zenhei-fonts
yum install -y cjkuni-uming-fonts
还有种办法,就是将windows中的字体都复制过来,将这个文件复制到自己定义的目录
有的环境,需要重新机器才能生效。
mkdir -p /usr/share/fonts/win/Fonts
chmod -R 755 /usr/share/fonts/win/Fonts
yum install ttmkfdir -y
ttmkfdir -e /usr/share/X11/fonts/encodings/encodings.dir
# 把你的目录配置进去
vim /etc/fonts/fonts.conf
# 刷新字体缓存
fc-cache
2 今天解决冲突的jar,结果出现下面的问题
java.lang.IllegalAccessError: tried to access method org.bouncycastle.asn1.DERNull.<init>()V from class com.itextpdf.text.pdf.security.PdfPKCS7
at com.itextpdf.text.pdf.security.PdfPKCS7.getEncodedPKCS7(PdfPKCS7.java:836)
at com.itextpdf.text.pdf.security.MakeSignature.signDetached(MakeSignature.java:154)
at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:97)
at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:157)
at com.whty.einv.sks.model.util.SignatureUtil.sign(SignatureUtil.java:143)
at com.whty.einv.sks.model.service.impl.LocalSignatureStrategy.sign(LocalSignatureStrategy.java:38)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:135)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:99)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.asyncGenPdf(AbstractInvoicePdfService.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Thr
按照kotlin 使用Itext5签署PDF在Quarkus中出现错误“PdfPKCS7无法访问void org.bouncycastle.asn1.DERNull.< init>()”
设置并不能解决问题。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
按照PDF文件的数字签名编写,再本地可以运行,但是发布到容器环境中,提示下面的错误,主要原还是因为bcprov-jdk15on
,因为jar冲突被排除了。
java.lang.NoClassDefFoundError: org/bouncycastle/jcajce/provider/digest/MD2$Digest
at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:111)
at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:83)
at com.whty.einv.sks.model.util.SignUtil.sign(SignUtil.java:69)
at com.whty.einv.sks.model.service.impl.LocalSignatureStrategy.sign(LocalSignatureStrategy.java:38)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:135)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.genPdf(AbstractInvoicePdfService.java:99)
at com.whty.einv.sks.model.service.AbstractInvoicePdfService.asyncGenPdf(AbstractInvoicePdfService.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jcajce.provider.digest.MD2$Digest
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:135)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 19 common frames omitted
现在对比一下新模式,这里的reason是必填,否则会报错,与旧模式有区别文章来源:https://www.toymoban.com/news/detail-703506.html
package com.whty.einv.sks.model.util;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.signatures.*;
import com.itextpdf.signatures.PdfSignatureAppearance.RenderingMode;
import com.whty.framework.base.util.CheckEmptyUtil;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
/**
* @author dj
* @create 2023-09-05 19:00
*/
public class SignUtil {
public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
}
public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
}
public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
}
public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
}
public static void sign(String src, String dest, String img, KeyStore keyStore, String password,String reason, String location) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), img, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, reason, location);
}
public static void sign(String src, OutputStream outputStream, KeyStore keyStore, String password) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, outputStream, null, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, "岁月云", "");
}
public static void sign(String src, OutputStream outputStream, String img, KeyStore keyStore, String password) throws GeneralSecurityException, IOException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, outputStream, img, chain, PrivateKey, DigestAlgorithms.SHA1, PdfSigner.CryptoStandard.CMS, null, null);
}
public static void sign(String src, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
PdfReader pdfReader = new PdfReader(src);
sign(pdfReader,outputStream,img,chain,pk,digestAlgorithm,sigtype,reason,location);
}
public static void sign(PdfReader pdfReader, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
PdfSigner.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException {
PdfSigner signer = new PdfSigner(pdfReader,outputStream,new StampingProperties());
// 获取数字签章属性对象,设定数字签章的属性
PdfSignatureAppearance appearance = signer.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
/**
* 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样
* 1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,
* 这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标
*/
Rectangle rect = new Rectangle(460, 0, 590, 90);
appearance.setReuseAppearance(false).setPageRect(rect).setPageNumber(1);
if(CheckEmptyUtil.isEmpty(img)) {
img = SignUtil.class.getClassLoader().getResource("seal/empty.png").getPath();
}
ImageData imageData = ImageDataFactory.create(img);
appearance.setSignatureGraphic(imageData);
appearance.setRenderingMode(RenderingMode.GRAPHIC);
/**
* 算法主要为:RSA、DSA、ECDSA
* 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现
*/
IExternalDigest digest = new BouncyCastleDigest();
/**
* 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者
*/
IExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);
signer.signDetached(digest, signature, chain, null, null, null, 0, sigtype);
}
}
旧模式,用法差不多,但是jar包的使用差异很大文章来源地址https://www.toymoban.com/news/detail-703506.html
package com.whty.einv.invoice.util;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.*;
import com.whty.framework.base.util.CheckEmptyUtil;
import org.apache.commons.io.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
/**
* 签名工具类
*/
public class SignatureUtil {
/**
* 签名
* @param pdfReader 需要签章的pdf
* @param dest 签完章的pdf文件路径
* @param chain 证书链
* @param img 印章图片
* @param pk 签名私钥
* @param digestAlgorithm 摘要算法名称,例如SHA-1
* @param sigtype 数字签名格式,itext有2种
* @param reason 签名的原因,显示在pdf签名属性中
* @param location 签名的地点,显示在pdf签名属性中
* @throws GeneralSecurityException
* @throws IOException
* @throws DocumentException
*/
public static void sign(PdfReader pdfReader, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype, String reason, String location,InputStream sealInputStream,int[] imageLocation) throws GeneralSecurityException, IOException, DocumentException {
/**
* 1 参数依次为:文件名、文件输入流、文件版本号、临时文件、是否可以追加签名
* 1.1 false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
* 1.2 true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
*/
// Create a PDF stamper
PdfStamper stamper = PdfStamper.createSignature(pdfReader, outputStream, '\0', null, false);
if(imageLocation == null){
imageLocation = new int[]{460, 0, 130, 90};
}
if(sealInputStream != null){
// Load the image
BufferedImage image = ImageIO.read(sealInputStream);
// Create a PDF image
Image pdfImage = Image.getInstance(image, null);
// Get the content of the first page
PdfContentByte content = stamper.getOverContent(1);
// Add the image to the specified location and with the specified dimensions
pdfImage.setAbsolutePosition(imageLocation[0], imageLocation[1]);
pdfImage.scaleAbsolute(imageLocation[2], imageLocation[3]);
content.addImage(pdfImage);
}
// 获取数字签章属性对象,设定数字签章的属性
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason(reason);
appearance.setLocation(location);
/**
* 1 三个参数依次为:设置签名的位置、页码、签名域名称,多次追加签名的时候,签名域名称不能一样
* 1.1 签名的位置四个参数:印章左下角的X、Y轴坐标,印章右上角的X、Y轴坐标,
* 这个位置是相对于PDF页面的位置坐标,即该坐标距PDF当前页左下角的坐标
*/
appearance.setVisibleSignature(new Rectangle(imageLocation[0], imageLocation[1], imageLocation[0]+imageLocation[2], imageLocation[1]+imageLocation[3]), 1, "sign");
/**
* 用于盖章的印章图片,引包的时候要引入itext包的image
*/
if(CheckEmptyUtil.isEmpty(img)) {
img = SignatureUtil.class.getClassLoader().getResource("seal/empty.png").getPath();
}
appearance.setSignatureGraphic(Image.getInstance(img));
/**
* 设置认证等级,共4种,分别为:
* NOT_CERTIFIED、CERTIFIED_NO_CHANGES_ALLOWED、
* CERTIFIED_FORM_FILLING 和 CERTIFIED_FORM_FILLING_AND_ANNOTATIONS
*
* 需要用哪一种根据业务流程自行选择
*/
appearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
/**
* 印章的渲染方式,同样有4种:
* DESCRIPTION、NAME_AND_DESCRIPTION,
* GRAPHIC_AND_DESCRIPTION,GRAPHIC;
* 这里选择只显示印章
*/
appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
/**
* 算法主要为:RSA、DSA、ECDSA
* 摘要算法,这里的itext提供了2个用于签名的接口,可以自己实现
*/
ExternalDigest digest = new BouncyCastleDigest();
/**
* 签名算法,参数依次为:证书秘钥、摘要算法名称,例如MD5 | SHA-1 | SHA-2.... 以及 提供者
*/
ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, null);
/**
* 最重要的来了,调用itext签名方法完成pdf签章
*/
MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, sigtype);
}
public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
}
public static void sign(String src, String dest, String img, KeyStore keyStore, String password, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), img, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
}
public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, reason, location);
}
public static void sign(String src, String dest, KeyStore keyStore, String password, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), null, chain, PrivateKey, digestAlgorithm, sigtype, null, null);
}
public static void sign(String src, String dest, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, new FileOutputStream(dest), null, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
}
public static void sign(String src, OutputStream outputStream, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, outputStream, null, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
}
public static void sign(String src, OutputStream outputStream, String img, KeyStore keyStore, String password) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey PrivateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
sign(src, outputStream, img, chain, PrivateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null);
}
public static void sign(String src, OutputStream outputStream, String img, Certificate[] chain, PrivateKey pk, String digestAlgorithm,
MakeSignature.CryptoStandard sigtype, String reason, String location) throws GeneralSecurityException, IOException, DocumentException {
PdfReader pdfReader = new PdfReader(src);
sign(pdfReader,outputStream,img,chain,pk,digestAlgorithm,sigtype,reason,location,null,null);
}
public static void sign(byte[] originalPdf, OutputStream outputStream, KeyStore keyStore, String password,InputStream sealInputStream,int[] imgLocation) throws GeneralSecurityException, IOException, DocumentException {
String alias = keyStore.aliases().nextElement();
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
Certificate[] chain = keyStore.getCertificateChain(alias);
PdfReader pdfReader = new PdfReader(originalPdf);
sign(pdfReader, outputStream, null, chain, privateKey, DigestAlgorithms.SHA1, MakeSignature.CryptoStandard.CMS, null, null,sealInputStream,imgLocation);
}
到了这里,关于pdf文件签名的问题解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!