在 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
DigestAlgorithm: 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")
}
}
确切地说,它们是我的问题的Signer和CertificateChains参数。我不知道如何正确使用 privateKey 和 chainCerts 变量。
我是这门语言的新手,所以我仍然不了解深入的概念和数据类型。
感谢您告诉我还应该做什么或缺少哪些步骤才能取得成功。或者如果有人知道我如何根据 pkcs 证书签署 pdf。
通常您希望从受信任的 CA 获取证书,目前您正在自己签名,这对于开发来说是可以的。
关于您的问题,您已经将这些变量分配给名为 SignDataSignature 的结构。您能更具体地说明您到底需要什么帮助吗?有错误吗