有人使用过unidoc给pdf加电子签章吗

ldwangaqr · · 223 次点击 · 开始浏览    置顶

需求是上传合同,然后给合同加上电子章,我看了一下unidoc库的示例。但是我签章之后,就显示签章无效,文件已经被修改或者损坏 package main import ( "crypto/rsa" "crypto/x509" "fmt" "image" "log" "os" "time" "github.com/unidoc/unipdf/v3/annotator" "github.com/unidoc/unipdf/v3/common/license" "github.com/unidoc/unipdf/v3/core" "github.com/unidoc/unipdf/v3/model" "github.com/unidoc/unipdf/v3/model/sighandler" "golang.org/x/crypto/pkcs12" ) func init() { // Make sure to load your metered License API key prior to using the library. // If you need a key, you can sign up and create a free one at https://cloud.unidoc.io err := license.SetMeteredKey(`8258c687d5bea0b89cb736d762de6937661d8f4562529b67b4ef478a2963d409`) if err != nil { panic(err) } } var now = time.Now() func main() { inputPath := `template_new.pdf` imageFile := `image.png` //watermarkImageFile := args[3] outputPath := `template_new2.pdf` // 读取PFX文件 pfxPath := "tanghuacomforthome.com.pfx" pfxPassword := "0gfn69iu" pfxData, err := os.ReadFile(pfxPath) if err != nil { log.Fatalf("无法读取PFX文件: %v", err) } // 解码PFX文件 priv, cert, err := DecodePFX(pfxData, pfxPassword) if err != nil { log.Fatalf("Fail: %v\n", err) } // Create reader. file, err := os.Open(inputPath) if err != nil { log.Fatalf("Fail: %v\n", err) } defer file.Close() reader, err := model.NewPdfReader(file) if err != nil { log.Fatalf("Fail: %v\n", err) } // Create the image imgFile, err := os.Open(imageFile) if err != nil { log.Fatalf("Fail: %v\n", err) } defer imgFile.Close() signatureImage, _, err := image.Decode(imgFile) if err != nil { log.Fatalf("Fail: %v\n", err) } // Create appender. appender, err := model.NewPdfAppender(reader) if err != nil { log.Fatalf("Fail: %v\n", err) } // Create signature handler. handler, err := sighandler.NewAdobePKCS7Detached(priv, cert) if err != nil { log.Fatalf("Fail: %v\n", err) } // Create signature. signature := model.NewPdfSignature(handler) signature.SetName("TangHua") signature.SetReason("Signature Appearance Reason") signature.SetDate(time.Now(), "") if err := signature.Initialize(); err != nil { log.Fatalf("Fail: %v\n", err) } // numPages, err := reader.GetNumPages() // if err != nil { // log.Fatal("Fail: %v\n", err) // } opts := annotator.NewSignatureFieldOpts() opts.FontSize = 10 opts.Rect = []float64{10, 25, 110, 75} opts.Image = signatureImage opts.ImagePosition = annotator.SignatureImageRight sigField, err := annotator.NewSignatureField( signature, []*annotator.SignatureLine{}, opts, ) if err != nil { log.Fatalf("Fail: %v\n", err) } sigField.T = core.MakeString(fmt.Sprintf("Signature %d", 1)) if err = appender.Sign(1, sigField); err != nil { log.Fatalf("Fail: %v\n", err) } err = appender.WriteToFile(outputPath) if err != nil { log.Fatalf("Fail: %v\n", err) } log.Printf("PDF file successfully signed. Output path: %s\n", outputPath) } // func generateKeys() (*rsa.PrivateKey, *x509.Certificate, error) { // // Generate private key. // priv, err := rsa.GenerateKey(rand.Reader, 2048) // if err != nil { // return nil, nil, err // } // // Initialize X509 certificate template. // template := x509.Certificate{ // SerialNumber: big.NewInt(1), // Subject: pkix.Name{ // Organization: []string{"Tanghua"}, // }, // NotBefore: now.Add(-time.Hour), // NotAfter: now.Add(time.Hour * 24 * 365), // KeyUsage: x509.KeyUsageDigitalSignature, // ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, // BasicConstraintsValid: true, // } // // Generate X509 certificate. // certData, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv) // if err != nil { // return nil, nil, err // } // cert, err := x509.ParseCertificate(certData) // if err != nil { // return nil, nil, err // } // return priv, cert, nil // } // DecodePFX 解码PFX文件并返回私钥和证书 func DecodePFX(pfxData []byte, password string) (*rsa.PrivateKey, *x509.Certificate, error) { // 使用pkcs12包解码PFX数据 blocks, err := pkcs12.ToPEM(pfxData, password) if err != nil { return nil, nil, err } var privateKey *rsa.PrivateKey var certificate *x509.Certificate for _, block := range blocks { switch block.Type { case "PRIVATE KEY": key, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, nil, err } privateKey = key case "CERTIFICATE": cert, err := x509.ParseCertificate(block.Bytes) if err != nil { return nil, nil, err } certificate = cert } } if privateKey == nil || certificate == nil { return nil, nil, fmt.Errorf("未找到私钥或证书") } return privateKey, certificate, nil }

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

223 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传