Skip to content

签名

福昕 PDF SDK 安卓版通过 Core SDK 提供了数字签名的创建、验证、删除和属性管理能力。通过数字签名,接收者可验证文档来源与内容是否被篡改。

UI Extensions 内置签名功能

如果您使用的是完整阅读器(UI Extensions),已内置数字签名模块(DigitalSignatureModule)和手写签名模块(SignatureModule),以及签名面板(SignaturePanelModule)用于查看和验证文档中的签名,无需额外编码。

默认支持的签名类型

SDK 内置默认签名回调,支持以下两种 filter/subfilter 组合,无需注册自定义回调:

  • Adobe.PPKLite + adbe.pkcs7.detached
  • Adobe.PPKLite + adbe.pkcs7.sha1

核心类

说明
Signature签名对象,管理签名的创建、签署、验证和属性。通过 PDFPage.addSignature() 创建,通过 PDFDoc.getSignature() 获取

签名键值常量

通过 setKeyValue(int key, String value) 设置签名信息:

常量说明
e_KeyNameSigner0签名人
e_KeyNameLocation1签名地点
e_KeyNameReason2签名原因
e_KeyNameContactInfo3联系信息
e_KeyNameDN4可辨别名称
e_KeyNameText5自定义文本

外观标志位常量

通过 setAppearanceFlags(int flags) 控制签名外观中显示的信息:

常量说明
e_APFlagLabel0x0002显示标签
e_APFlagReason0x0004显示签名原因
e_APFlagSigningTime0x0008显示签名时间
e_APFlagDN0x0010显示 DN
e_APFlagLocation0x0020显示签名地点
e_APFlagSigner0x0040显示签名人
e_APFlagBitmap0x0080显示图片
e_APFlagText0x0100显示自定义文本

摘要算法常量

常量说明
e_DigestSHA10SHA-1
e_DigestSHA2561SHA-256
e_DigestSHA3842SHA-384
e_DigestSHA5123SHA-512

常用验证状态常量

验证完成后通过 getState() 获取,使用位与判断:

常量说明
e_StateUnsigned未签署
e_StateSigned已签署
e_StateVerifyValid签名有效
e_StateVerifyInvalid签名无效
e_StateVerifyChange文档已被修改
e_StateVerifyNoChange文档未被修改
e_StateVerifyIssueValid签发者证书有效
e_StateVerifyIssueExpire签发者证书过期

示例:签署并验证

java
import com.foxit.sdk.pdf.PDFDoc;
import com.foxit.sdk.pdf.PDFPage;
import com.foxit.sdk.pdf.Signature;
import com.foxit.sdk.common.Progressive;
import com.foxit.sdk.common.fxcrt.RectF;

PDFDoc doc = new PDFDoc("path/to/Sample.pdf");
doc.load(null);
PDFPage page = doc.getPage(0);

// 添加签名域
Signature signature = page.addSignature(new RectF(100, 600, 300, 700));

// 设置外观
signature.setAppearanceFlags(
    Signature.e_APFlagLabel | Signature.e_APFlagDN |
    Signature.e_APFlagReason | Signature.e_APFlagSigner |
    Signature.e_APFlagSigningTime | Signature.e_APFlagLocation
);

// 设置签名信息
signature.setKeyValue(Signature.e_KeyNameSigner, "张三");
signature.setKeyValue(Signature.e_KeyNameLocation, "北京");
signature.setKeyValue(Signature.e_KeyNameReason, "文档审批");
signature.setFilter("Adobe.PPKLite");
signature.setSubFilter("adbe.pkcs7.detached");

// 签署
Progressive progressive = signature.startSign(
    "/sdcard/cert.pfx", "123".getBytes(),
    Signature.e_DigestSHA256, "/sdcard/signed.pdf", null, null);
int state = Progressive.e_ToBeContinued;
while (state == Progressive.e_ToBeContinued) {
    state = progressive.resume();
}

// 验证已签署文档中的所有签名
PDFDoc signedDoc = new PDFDoc("/sdcard/signed.pdf");
signedDoc.load(null);

int count = signedDoc.getSignatureCount();
for (int i = 0; i < count; i++) {
    Signature sig = signedDoc.getSignature(i);
    if (sig == null || sig.isEmpty()) continue;

    Progressive verifyProgress = sig.startVerify(null, null);
    int vState = Progressive.e_ToBeContinued;
    while (vState == Progressive.e_ToBeContinued) {
        vState = verifyProgress.resume();
    }

    int verifiedState = sig.getState();
    if ((verifiedState & Signature.e_StateVerifyValid) != 0) {
        // 签名有效
    }
}

示例:设置自定义签名时间

setSignTime 当前不支持直接修改时间格式。如需设置自定义格式的时间,可将时间字符串写入签名词典:

java
Signature signature = page.addSignature(rect);
signature.setAppearanceFlags(Signature.e_APFlagSigningTime | Signature.e_APFlagSigner);

PDFDictionary dict = signature.getSignatureDict();
dict.setAtString("M", "2025/01/14 10:30:00");

API 参考

Signature 的完整接口说明请参阅 API 手册