电子签名、电子签章已经不是个陌生的东西了。在java领域使用itextpdf可以完成pdf的电子签名。当然最终是以pkcs7的格式存储在pdf文件中。类似
我们知道pkcs7是RSA体系中的,属于国际标准。我们国家的国密标准也早就出台了,那是否能实现国密的数字签名呢?答案是肯定的可以。
方案一、
itextpdf+修改源代码+bouncycastle
MakeSignature.signDetached(appearance, digest, pks,
chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);
修改MakeSignature类及相关的几个类,核心就是修改PdfPKCS7类。bouncycastle本身就支持
sm2 sm3等国密算法
复制代码
方案二、
itextpdf+signExternalContainer+bouncycastle
ExternalSignatureContainer external =
new HashExternalSignatureContainer(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);
itextpdf已经提供signExternalContainer来让用户自定义签名
复制代码
当然还有个关键问题就是如何把pkcs7换成国密的数据结构,我们知道国密的数据结构是asn.1编码的,当然pkcs7也是asn.1编码,只不过两者的数据结构体不一样。在java中可以使用bouncycastle来完成签名后的数据序列化成国密要求的数据结构。
step1
先按照《安全电子签章密码技术规范》国密标准生成java对象
@Data
@Builder
public class SESHeader extends ASN1Object {
//头标识
private DERIA5String id;
//印章版本号
private ASN1Integer version;
//厂商标识
private DERIA5String vid;
@Override
public ASN1Primitive toASN1Primitive() {
ASN1EncodableVector vector = new ASN1EncodableVector();
vector.add(id);
vector.add(version);
vector.add(vid);
return new DERSequence(vector);
}
}
复制代码
step2
创建好对象后,就可以序列化成byte[]
byte[] encode = signature.toASN1Primitive().getEncoded();
复制代码
step3
生成16进制就可以放置在pdf中了
Hex.toHexString(paddedSig)
复制代码




近期评论