Skip to content

创建数字签名

创建数字签名分为两个步骤:

  1. 创建签名域

  2. 在签名域填写签名

通过这两个步骤,您可以自签文件,或邀请其他人在您创建的签名域进行签名。

创建签名域

ComPDFKit 支持自定义签名域表单样式,以及通过文字,图片,手绘来自定义签名外观。

以下是创建签名域的关键代码:

java
// 创建签名域。
// 
// Page Index: 0
// Rect: CRect(28, 420, 150, 370)
// Border RGB:{ 0, 0, 0 }  
// Widget Background RGB: { 150, 180, 210 }
// 
CPDFDocument document = new CPDFDocument(context);
document.open(FileUtils.getAssetsTempFile(context, "CommonFivePage.pdf"));
// 插入一个表单签名 Widget (unsigned)
CPDFPage cpdfPage = document.pageAtIndex(0);
RectF pageSize = cpdfPage.getSize();
RectF signatureRect = new RectF(28, 420, 150, 370);
signatureRect = cpdfPage.convertRectToPage(false, pageSize.width(), pageSize.height(), signatureRect);
CPDFSignatureWidget signatureWidget = (CPDFSignatureWidget) cpdfPage.addFormWidget(CPDFWidget.WidgetType.Widget_SignatureFields);
signatureWidget.setFieldName("Signature1");
signatureWidget.setFillColor(0xFF96B4D2);
signatureWidget.setRect(signatureRect);
signatureWidget.updateAp();
kotlin
// 创建签名域。
// 
// Page Index: 0
// Rect: CRect(28, 420, 150, 370)
// Border RGB:{ 0, 0, 0 }  
// Widget Background RGB: { 150, 180, 210 }
// 
val document = CPDFDocument(context())
document.open(getAssetsTempFile(context(), "CommonFivePage.pdf"))
// 插入一个表单签名 Widget (unsigned)
val cpdfPage = document.pageAtIndex(0)
val pageSize = cpdfPage.size
val signatureWidget = cpdfPage.addFormWidget(CPDFWidget.WidgetType.Widget_SignatureFields) as CPDFSignatureWidget
signatureWidget.fieldName = "Signature1"
signatureWidget.fillColor = Color.parseColor("#FF96B4D2")
signatureWidget.rect = kotlin.run {
  cpdfPage.convertRectToPage(false, pageSize.width(), pageSize.height(), RectF(28f, 420f, 150f, 370f))
}
signatureWidget.updateAp()

在签名域中填写签名

在签名域中填写签名的步骤如下:

  1. 持有一个 PKCS12 标准的证书(PFX 或 P12 格式),并确保知道它的密码,您可以通过 ComPDFKit SDK 内置的方法创建符合标准的数字证书。

  2. 通过 ComPDFKit 的接口设定数字签名的外观。

  3. 将数据写入签名域并保存。

在签名域中填写签名的示例代码如下:

java
// 在签名域签名。
//
// Text: Grantor Name
// Content:
// Name: get grantor name from certificate
// Date: now(yyyy.mm.dd)
// Reason: I am the owner of the document.
// DN: Subject
// IsContentAlginLeft: false
// IsDrawLogo: True
// LogoBitmap: logo.png
// text color RGB: { 0, 0, 0 }
// 输出的文件名: document.FileName + "_Signed.pdf"
//
String fileName = FileUtils.getNameWithoutExtension(document.getFileName()) + "_Signed.pdf";
File file = new File(outputDir(), "digitalSignature/" + fileName);
file.getParentFile().mkdirs();
String password = "ComPDFKit";

String certPath = FileUtils.getAssetsTempFile(context, "Certificate.pfx");
CPDFX509 cpdfx509 = CPDFSignature.getX509ByPKCS12Cert(certPath, password);
String location = cpdfx509.getCertInfo().getSubject().getCountry();
String reason = "I am the owner of the document.";

Bitmap bitmap = BitmapFactory.decodeFile(FileUtils.getAssetsTempFile(context, "ComPDFKit.png"));
// 描述签名外观信息。
CPDFDigitalSigConfig sigConfig = new CPDFDigitalSigConfig();
sigConfig.setText(cpdfx509.getCertInfo().getSubject().getCommonName());
sigConfig.setTextColor(0xFF000000);
sigConfig.setContentColor(0xFF000000);
sigConfig.setLogo(bitmap);
StringBuilder builder = new StringBuilder();
builder.append("Name: ").append(cpdfx509.getCertInfo().getSubject().getCommonName()).append("\n")
  .append("Date: ").append(DateUtil.getDataTime("yyyy.MM.dd HH:mm:ss")).append("\n")
  .append("Reason: ").append(reason).append("\n")
  .append("Location: ").append(location).append("\n")
  .append("DN: ").append(cpdfx509.getCertInfo().getSubject());
sigConfig.setContent(builder.toString());
sigConfig.setContentAlginLeft(false);
sigConfig.setDrawLogo(true);

boolean updateSignAp = signatureWidget.updateApWithDigitalSigConfig(sigConfig);
if (updateSignAp){
  boolean writeSignResult = document.writeSignature(
    signatureWidget,
    file.getAbsolutePath(),
    certPath,
    password,
    location,
    reason,
    CPDFDocument.PDFDocMdpP.PDFDocMdpPForbidAllModify
  );
}
kotlin
//	   在签名域签名。
//
// 	   Text: Grantor Name
// 	   Content:
//     Name: get grantor name from certificate
//     Date: now(yyyy.mm.dd)
//     Reason: I am the owner of the document.
//     DN: Subject
//     IsContentAlginLeft: false
//     IsDrawLogo: True
//     LogoBitmap: logo.png
//     text color RGB: { 0, 0, 0 }
//     输出的文件名: document.FileName + "_Signed.pdf"
//
// 创建一个数字签名。
val fileName = getNameWithoutExtension(document.fileName) + "_Signed.pdf"
val file = File(outputDir(), "digitalSignature/$fileName")
file.parentFile?.mkdirs()
val password = "ComPDFKit"
val certPath = getAssetsTempFile(context(), "Certificate.pfx")
val cpdfx509 = CPDFSignature.getX509ByPKCS12Cert(certPath, password)
val location = cpdfx509.certInfo.subject.country
val reason = "I am the owner of the document."
val bitmap = BitmapFactory.decodeFile(getAssetsTempFile(context(), "ComPDFKit.png"))
// 描述签名外观信息。
val sigConfig = CPDFDigitalSigConfig().apply {
  text = cpdfx509.certInfo.subject.commonName
  textColor = Color.BLACK
  contentColor = Color.BLACK
  logo = bitmap
  val builder = StringBuilder()
  builder.append("Name: ").append(cpdfx509.certInfo.subject.commonName).append("\n")
  .append("Date: ").append(DateUtil.getDataTime("yyyy.MM.dd HH:mm:ss")).append("\n")
  .append("Reason: ").append(reason).append("\n")
  .append("Location: ").append(location).append("\n")
  .append("DN: ").append(cpdfx509.certInfo.subject)
  content = builder.toString()
  isContentAlginLeft = false
  isDrawLogo = true
}
val updateSignAp = signatureWidget.updateApWithDigitalSigConfig(sigConfig)
if (updateSignAp) {
  val writeSignResult = document.writeSignature(
    signatureWidget,
    file.absolutePath,
    certPath,
    password,
    location,
    reason,
    CPDFDocument.PDFDocMdpP.PDFDocMdpPForbidAllModify
  )
}