有人使用过unidoc数字签名吗 | go | go 技术论坛-380玩彩网官网入口

公司要做上传合同电子签章,我的证书是用的阿里云买的ssl证书,下载下来的pfx文件,签名后打开一直显示文件签名后被修改或者已损坏,下面是我最后改来改去的最终版,如果不使用pfx证书,用generatekeys生成就不会显示被修改。

package main
import (
    "bytes"
    "crypto"
    "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.
    timestampserverurl := "https://freetsa.org/tsr"
    handler, err := sighandler.newetsipadeslevellt(priv, cert, nil, timestampserverurl, appender)
    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
    field, err := annotator.newsignaturefield(
        signature,
        []*annotator.signatureline{},
        opts,
    )
    if err != nil {
        log.fatalf("fail: %v\n", err)
    }
    field.t = core.makestring(fmt.sprintf("signature %d", 1))
    if err = appender.sign(1, field); err != nil {
        log.fatalf("fail: %v\n", err)
    }
    // write to buffer
    buffer := bytes.newbuffer(nil)
    err = appender.write(buffer)
    if err != nil {
        log.fatalf("error writing to buffer: %v\n", err)
    }
    // second pass to save dss/vri information
    pdf2, err := model.newpdfreader(bytes.newreader(buffer.bytes()))
    if err != nil {
        log.fatalf("error creating pdf reader for second pass: %v\n", err)
    }
    appender2, err := model.newpdfappender(pdf2)
    if err != nil {
        log.fatalf("error creating pdf appender for second pass: %v\n", err)
    }
    appender2.setdss(appender.getdss())
    buf2 := bytes.newbuffer(nil)
    err = appender2.write(buf2)
    if err != nil {
        log.fatalf("error writing second pass buffer: %v\n", err)
    }
    // document timestamp for b-lta compatibility
    pdf3, err := model.newpdfreader(bytes.newreader(buf2.bytes()))
    if err != nil {
        log.fatalf("error creating pdf reader for timestamp: %v\n", err)
    }
    appender3, err := model.newpdfappender(pdf3)
    if err != nil {
        log.fatalf("error creating pdf appender for timestamp: %v\n", err)
    }
    handler, err = sighandler.newdoctimestamp(timestampserverurl, crypto.sha512)
    if err != nil {
        log.fatalf("error creating timestamp handler: %v\n", err)
    }
    signature = model.newpdfsignature(handler)
    signature.setname("test signature")
    signature.setdate(time.now(), "")
    err = signature.initialize()
    if err != nil {
        log.fatalf("error initializing timestamp signature: %v\n", err)
    }
    opts = annotator.newsignaturefieldopts()
    opts.rect = []float64{10, 25, 110, 75}
    opts.image = signatureimage
    sigfield, err := annotator.newsignaturefield(
        signature,
        []*annotator.signatureline{},
        opts,
    )
    if err != nil {
        log.fatalf("error creating timestamp signature field: %v\n", err)
    }
    err = appender3.sign(1, sigfield)
    if err != nil {
        log.fatalf("error signing with timestamp: %v\n", err)
    }
    err = appender3.writetofile(outputpath)
    if err != nil {
        log.fatalf("error writing final output file: %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
}
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图