解析pdf电子签章

Java使用itext解析pdf签章

前言

许多业务交易(包括金融、法律和其他受管制交易)都要求在对文档进行签名时提供较高程度的保证。当以电子方式分发文档时,收件人务必可以:

  • 验证文档真实性 — 确认对文档进行签名的每个人的身份
  • 验证文档完整性 — 确认在传输过程中文档未被更改

那么我们怎么通过程序鉴别一个带有电子签章的pdf签章的有效性呢?


电子签章

电子签章有签名时间,签章有效期起止时间,从这三个时间我们就可以看一些基本的签章有效性和时间是否合理(是否被篡改)。

解析电子签章

我们利用itext来解析电子签章。

读取加载pdf

通过读取pdf的url,将内容加载到流中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static InputStream getInputStreamByUrl(String strUrl) {
HttpURLConnection conn = null;
try {
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(20 * 1000);
final ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(conn.getInputStream(), output);
return new ByteArrayInputStream(output.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

解析签章时间

我们主要用到com.itextpdf.text.pdf里的三个:AcroFieldsPdfReadersecurity.PdfPKCS7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import com.google.gson.Gson;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import com.xiaoying.risksystem.util.StackTraceUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// ...

public GsonResponse resolvePdf(Integer applyId, String pdfUrl) throws IOException, GeneralSecurityException {


GsonResponse gsonResponse = new GsonResponse();

try {
String signed_on = ""; // 签名时间
String valid_to = ""; // 有效期开始时间
String valid_from = ""; // 有效期截止时间

SimpleDateFormat date_format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
InputStream resource = getInputStreamByUrl(pdfUrl);
PdfReader reader = new PdfReader(resource); //pdf reader 读取流内容
AcroFields fields = reader.getAcroFields(); // 获取Acro字段
ArrayList<String> names = fields.getSignatureNames(); // 获取Acro字段里的签名信息
for (String name : names) {
PdfPKCS7 pkcs7 = fields.verifySignature(name); // 获取签名的pkcs7数据
signed_on = date_format.format(pkcs7.getSignDate().getTime()); // 获取转换pkcs7数据里的签名日期时间
valid_from = date_format.format(pkcs7.getSigningCertificate().getNotBefore()); // 获取pkcs7数据里有效期开始时间
valid_to = date_format.format(pkcs7.getSigningCertificate().getNotAfter()); // 获取pkcs7数据里有效期

}

GsonResponse.DataBean dataBean = new GsonResponse.DataBean();
dataBean.setSigned_on(signed_on);
dataBean.setValid_from(valid_from);
dataBean.setValid_to(valid_to);
gsonResponse.setData(dataBean);
} catch (Exception e) {
Log.error("applyId:{} itextPdf except:{}", applyId, StackTraceUtils.getStackTrace(e));
gsonResponse.setErr_code(-1);
} finally {
return gsonResponse;
}

}

签章有效性

这样我们可以获取到三个时间了,一般可以通过签名时间和有效期时间是否为同一天或者看当前日期是否在有效期内来判断签章的有效期行,此外我们也可以利用函数来判断:

1
2
3
PdfPKCS7 pkcs7 = fields.verifySignature(name); // 获取签名的pkcs7数据
boolean isValid = pkcs7.verifySignatureIntegrityAndAuthenticity(); //数字签名验证是否有效
Sysetm.out.println("Is signature valid: " + isValid)

小结

有时候我们设计到pdf合同的有效性的时候,可以用itextpdf来读取解析其签章时间来判定合同签章的有效性。

-------------阅读完毕吐槽一番吧~-------------
0%