Skip to content

创建数字签名

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

  1. 创建签名域。

  2. 在签名域填写签名。

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

创建签名域

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

创建签名域关键代码:

swift
// 创建签名域。
// 
// Page Index: 0
// Rect: CRect(28, 420, 150, 370)
// Border RGB:{ 0, 0, 0 }  
// Widget Background RGB: { 150, 180, 210 }
// 

if let url = Bundle.main.url(forResource: "filename", withExtension: "pdf") {
    let document = CPDFDocument(url: url)
    if let page = document?.page(at: 0) {
        let widgetAnnotation = CPDFSignatureWidgetAnnotation(document: document)
        
        widgetAnnotation.fieldName = "Signature_\(self.tagString())"
        widgetAnnotation.borderWidth = 2.0
        widgetAnnotation.bounds = CGRect(x: 28, y: 420, width: 150, height: 370)
        widgetAnnotation.modificationDate = Date()
        
        page.addAnnotation(widgetAnnotation)
    }
}
objective-c
// 创建签名域。
// 
// Page Index: 0
// Rect: CRect(28, 420, 150, 370)
// Border RGB:{ 0, 0, 0 }  
// Widget Background RGB: { 150, 180, 210 }
// 

NSURL *url = [NSURL fileURLWithPath:@"file path"];

CPDFDocument *document = [[CPDFDocument alloc] initWithURL:url];
CPDFPage *page = [document pageAtIndex:0];

CPDFSignatureWidgetAnnotation *widgetAnnotation = [[CPDFSignatureWidgetAnnotation alloc] initWithDocument:self.document];

[widgetAnnotation setFieldName:[NSString stringWithFormat:@"%@%@",@"Signature_",[self tagString]]];

widgetAnnotation.borderWidth = 2.0;
widgetAnnotation.bounds = CGRectMake(28, 420, 150, 370);
[widgetAnnotation setModificationDate:[NSDate date]];
[page addAnnotation:widgetAnnotation];

在签名域中填写签名

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

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

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

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

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

swift
// 在签名域签名。
//
// 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"
//

let writeDirectoryPath = NSHomeDirectory().appending("/Documents/Signatures")
let documentURL = self.pdfListView?.document.documentURL
let documentName = documentURL?.lastPathComponent.components(separatedBy: ".").first ?? ""
let writeFilePath = writeDirectoryPath + "/" + "\(documentName)_Signed_\(tagString()).pdf"

if FileManager.default.fileExists(atPath: writeFilePath) {
    try? FileManager.default.removeItem(at: URL(fileURLWithPath: writeFilePath))
}

let contents = CPDFSignatureConfig()
signatureConfig.text = nil
signatureConfig.isDrawOnlyContent = true
signatureConfig.image = image

signatureConfig.isContentAlginLeft = false
signatureConfig.isDrawLogo = true
signatureConfig.isDrawKey = true
signatureConfig.logo = UIImage(named: "ImageNameDigitalSignature", in: Bundle(for: self.classForCoder), compatibleWith: nil)

var contents = signatureConfig.contents ?? []

let configItem1 = CPDFSignatureConfigItem()
configItem1.key = "Digitally signed by Apple Distribution"
configItem1.value = NSLocalizedString(self.signatureCertificate?.issuerDict["CN"] as? String ?? "", comment: "")
contents.append(configItem1)

let configItem2 = CPDFSignatureConfigItem()
configItem2.key = "Date"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
configItem2.value = dateFormatter.string(from: Date())
contents.append(configItem2)

let configItem3 = CPDFSignatureConfigItem()
configItem3?.key = "DN"
let dn = signatureCertificate?.issuerDict["C"]
configItem3?.value = NSLocalizedString(dn, comment: "")
contents3.append(configItem)

let configItem4 = CPDFSignatureConfigItem()
configItem4?.key = VERSION_KEY
configItem4?.value = infoDictionary["CFBundleShortVersionString"] as? String
contents.append(configItem4)

let configItem5 = CPDFSignatureConfigItem()
configItem5?.key = "Location"
configItem5?.value = NSLocalizedString("<your signing location here>", comment: "")
contents.append(configItem5)

let configItem6 = CPDFSignatureConfigItem()
configItem6?.key = "Reason"
configItem6?.value = NSLocalizedString("<your signing reason here>", comment: "")
contents.append(configItem6)

annotation?.signAppearanceConfig(signatureConfig)

let isSuccess = self.pdfListView?.document.writeSignature(to: URL(fileURLWithPath: writeFilePath), withWidget: widget, pkcs12Cert: path, password: password, location: locationStr, reason: reasonStr, permissions: .none) ?? false
objective-c
// 在签名域签名。
//
// 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"
//

NSString *homePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSString *writeDirectoryPath = [NSString stringWithFormat:@"%@/%@", homePath, @"Signature"];

if (![[NSFileManager defaultManager] fileExistsAtPath:writeDirectoryPath])
[[NSFileManager defaultManager] createDirectoryAtURL:[NSURL fileURLWithPath:writeDirectoryPath] withIntermediateDirectories:YES attributes:nil error:nil];

NSString *writeFilePath = [NSString stringWithFormat:@"%@/%@_Signed_%@.pdf",writeDirectoryPath,self.pdfListView.document.documentURL.lastPathComponent.stringByDeletingPathExtension,[self tagString]];
if([[NSFileManager defaultManager] fileExistsAtPath:writeFilePath]) {
[[NSFileManager defaultManager] removeItemAtPath:writeFilePath error:nil];
}

CPDFSignatureConfig *signatureConfig = [[CPDFSignatureConfig alloc] init];
signatureConfig.image = image;
signatureConfig.isContentAlginLeft = NO;
signatureConfig.isDrawLogo = YES;
signatureConfig.isDrawKey = YES;
signatureConfig.logo = [UIImage imageNamed:@"ImageNameDigitalSignature"];

NSMutableArray *contents = [NSMutableArray arrayWithArray:signatureConfig.contents];

CPDFSignatureConfigItem *configItem1 = [[CPDFSignatureConfigItem alloc]init];
configItem1.key = @"Digitally signed by Apple Distribution";
configItem1.value = NSLocalizedString([signatureCertificate.issuerDict objectForKey:@"CN"], nil);
[contents addObject:configItem1];

CPDFSignatureConfigItem *configItem2 = [[CPDFSignatureConfigItem alloc]init];
configItem2.key = @"Date";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
configItem2.value = [dateFormatter stringFromDate:[NSDate date]];
[contents addObject:configItem2];

CPDFSignatureConfigItem *configItem3 = [[CPDFSignatureConfigItem alloc]init];
configItem3.key = @"DN";
configItem3.value = NSLocalizedString([signatureCertificate.subjectDict objectForKey:@"C"], nil);
[contents addObject:configItem3];

CPDFSignatureConfigItem *configItem4 = [[CPDFSignatureConfigItem alloc]init];
configItem4.key = @"ComPDFKit Version";
NSDictionary*infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
configItem4.value = app_Version;
[configItem4 addObject:configItem4];

CPDFSignatureConfigItem *configItem5 = [[CPDFSignatureConfigItem alloc]init];
configItem5.key = @"Reason";
configItem5.value = NSLocalizedString(@"I am the owner of the document.", nil);
[contents addObject:configItem5];

CPDFSignatureConfigItem *configItem6 = [[CPDFSignatureConfigItem alloc]init];
configItem6.key = @"Location";
configItem6.value = NSLocalizedString(@"<your signing location here>", nil);
[contents addObject:configItem6];

signatureConfig.contents = contents;
[widgetAnnotation signWithSignatureConfig:signatureConfig];

BOOL isSuccess = [document writeSignatureToURL:[NSURL fileURLWithPath:writeFilePath] withWidget:widgetAnnotation PKCS12Cert:@"Certificate path" password:@"123" location:@"<your signing location here>" reason:@"I am the owner of the document." permissions:CPDFSignaturePermissionsNone];