在Go(Golang)中,我需要签署一份pdf文档,但与其他语言不同的是,没有库可以让这项工作变得更容易.我已经找到了几个付费的,但它们不是一个选项.
首先,我有一个PKCS证书(.p12),我已经使用以下包从中提取了私钥和x509证书:https://pkg.go.dev/software.sslmate.com/src/go-pkcs12
但是当我想签署pdf文档时,我被卡住了,因为我不知道如何正确地将参数传递给执行此类操作的函数.使用的包装是https://pkg.go.dev/github.com/digitorus/pdfsign
我的完整代码是:
package main
import (
"crypto"
"fmt"
"os"
"time"
"github.com/digitorus/pdf"
"github.com/digitorus/pdfsign/revocation"
"github.com/digitorus/pdfsign/sign"
gopkcs12 "software.sslmate.com/src/go-pkcs12"
)
func main() {
certBytes, err := os.ReadFile("certificate.p12")
if err != nil {
fmt.Println(err)
return
}
privateKey, certificate, chainCerts, err := gopkcs12.DecodeChain(certBytes, "MyPassword")
if err != nil {
fmt.Println(err)
return
}
input_file, err := os.Open("input-file.pdf")
if err != nil {
fmt.Println(err)
return
}
defer input_file.Close()
output_file, err := os.Create("output-file.pdf")
if err != nil {
fmt.Println(err)
return
}
defer output_file.Close()
finfo, err := input_file.Stat()
if err != nil {
fmt.Println(err)
return
}
size := finfo.Size()
rdr, err := pdf.NewReader(input_file, size)
if err != nil {
fmt.Println(err)
return
}
err = sign.Sign(input_file, output_file, rdr, size, sign.SignData{
Signature: sign.SignDataSignature{
Info: sign.SignDataSignatureInfo{
Name: "John Doe",
Location: "Somewhere on the globe",
Reason: "My season for siging this document",
ContactInfo: "How you like",
Date: time.Now().Local(),
},
CertType: sign.CertificationSignature,
DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms,
},
Signer: privateKey, // crypto.Signer
Digest算法rithm: crypto.SHA256, // hash algorithm for the digest creation
Certificate: certificate, // x509.Certificate
CertificateChains: chainCerts, // x509.Certificate.Verify()
TSA: sign.TSA{
URL: "https://freetsa.org/tsr",
Username: "",
Password: "",
},
// The follow options are likely to change in a future release
//
// cache revocation data when bulk signing
RevocationData: revocation.InfoArchival{},
// custom revocation lookup
RevocationFunction: sign.DefaultEmbedRevocationStatusFunction,
})
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Signed PDF written to output.pdf")
}
}
准确地说,他们是我的问题所在的签名者和证书链参数.我不知道如何正确使用Private Key和chainCerts变量.
错误消息包括:
- 无法使用PriateKey(接口类型为{}的变量)作为加密. struct 文本中的Signer值:接口{}未实现加密.Signer(缺少方法Public)
- 不能将chaincerfates(类型为[]*x509证书的变量)用作[][]*x509 struct 文本中的证书值
我是这种语言的新手,所以我仍然不知道深入的概念和数据类型.
我感谢你告诉我我还应该做些什么,或者是为了达成一个成功的结论而遗漏了哪些步骤.或者是否有人知道我如何基于PKCS证书来签署PDF.