需求是上传合同,然后给合同加上电子章,我看了一下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
}
有疑问加站长微信联系(非本文作者)
