Go 언어로 PDF 파일에 서명하는 것은 일반적인 요구 사항이며 이 기능은 digitalorus/pdfsign 라이브러리를 사용하여 쉽게 구현할 수 있습니다. PHP 편집자 Youzi가 이 라이브러리를 사용하는 방법을 소개합니다. 비즈니스 응용 프로그램이든 개인 프로젝트이든 PDF 파일에 서명하는 것은 일반적인 작업입니다. digitalorus/pdfsign 라이브러리는 간단하고 사용하기 쉬운 인터페이스를 제공하여 Go 언어로 PDF 파일에 간단하고 빠르게 서명할 수 있도록 해줍니다. 이 기사를 통해 Go 언어로 digitalorus/pdfsign 라이브러리를 사용하여 PDF 파일의 서명 작업을 완료하는 방법을 배우게 됩니다. 함께 탐험해 보세요!
go(golang)에서는 PDF 문서에 서명을 해야 하는데 다른 언어와는 달리 작업을 쉽게 해주는 라이브러리가 없습니다. 유료 제품을 몇 개 찾았지만 옵션이 아니었습니다.
먼저 다음 패키지를 사용하여 개인 키와 x509 인증서를 추출한 PKCS 인증서(.p12)가 있습니다. https://pkg.go.dev/software.sslmate.com/src/go -pkcs12
그런데 PDF 문서에 서명하려고 할 때 이러한 작업을 수행하는 함수에 매개변수를 올바르게 전달하는 방법을 모르기 때문에 막히게 됩니다. 사용된 패키지는 https://pkg.go.dev/github.com/digitorus/pdfsign
내 전체 코드는 다음과 같습니다:
으아악정확히 말하면 제 질문의 Signer 및 CertificateChains 매개변수입니다. privateKey 및 chainCerts 변수를 올바르게 사용하는 방법을 모르겠습니다.
메시지 오류:
저는 이 언어를 처음 접해서 아직 심층적인 개념과 데이터 유형을 이해하지 못합니다.
성공하기 위해 무엇을 더 해야 하는지, 어떤 단계를 놓치고 있는지 알려주셔서 감사합니다. 또는 pkcs 인증서를 기반으로 PDF에 서명하는 방법을 아는 사람이 있다면.
디지털 서명을 사용하여 PDF에 서명하려면 공개 키 암호화를 사용하여 키 쌍을 생성해야 합니다. 개인 키는 서명과 관련된 데이터를 암호화하는 데 사용되며 서명자만 액세스할 수 있으며, 공개 키는 검증을 위해 서명 데이터를 해독하는 데 사용됩니다. 인증서를 신뢰할 수 있도록 하려면 인증서를 인증서 저장소에 추가해야 합니다. 주어진 예에서 이 서명 데이터는 pdfsign 라이브러리의 일부인 sign.SignData라는 구조 내에 저장되며 x509 인증서와 crypto.Signer 인터페이스를 구현하는 서명자가 필요합니다.
첫 번째 단계는 Go 표준 라이브러리의 crypto/ecdsa 패키지를 사용하여 키 쌍을 생성하는 것입니다. GenerateKey는 개인 키와 공개 키를 privateKey 변수에 저장합니다. 이 반환된 privateKey 변수는 현재 직면한 문제를 해결하는 데 필요한 crypto.Signer 인터페이스를 구현합니다.
ecdsa.go 코드의 142번째 줄을 읽어보면 이를 확인할 수 있습니다.
현재 gopkcs12.DecodeChain을 사용하여 개인 키를 반환하고 있지만 crypto.Signer 인터페이스를 구현하지 않아 오류가 발생합니다. 사용자 정의 구현이 필요할 수도 있지만 이는 또 다른 질문입니다.
콘셉트:
ECDSA는 타원 곡선 디지털 서명 알고리즘을 나타냅니다. 디지털 서명에 사용되는 공개 키 암호화 알고리즘입니다. 자세한 내용은 Go 표준 라이브러리 문서와 NIST 웹사이트를 참조하세요.
NIST P-384: P-384는 NIST(미국 국립표준기술원)에서 권장하는 키 길이가 384비트인 타원 곡선 중 하나입니다. 디지털 서명 및 권장되는 타원 곡선에 대한 자세한 내용은 NIST 웹 사이트를 참조하세요. 저는 P-384를 작업 솔루션으로 사용합니다.
第二步是使用Go标准库中的crypto/x509包通过其链生成器生成x509证书和证书链。这些是您在问题中寻求帮助的特定变量,但不属于您在错误消息中可以清楚看到的预期类型。只需遵循 lib 指令并使用 x509.Certificate.Verify() 就像我在工作解决方案中所做的那样,这将返回正确的类型 [][]*x509.Certificate。
请参阅 Go 标准库文档以获取更多信息。
第三步是打开输入 pdf 文件并使用 Go 标准库中的 os 包创建输出 pdf 文件。
第四步实际上是使用 digitalorus/pdfsign 库对 pdf 文件进行签名。
这是我今天编码和测试的一个有效解决方案,旨在让您回到正轨,进行一些研究并根据您的需求进行修改:
package main import ( "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "fmt" "github.com/digitorus/pdf" "github.com/digitorus/pdfsign/revocation" "github.com/digitorus/pdfsign/sign" "log" "math/big" "os" "time" ) func main() { // First step privateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) if err != nil { panic(err) } // Second step x509RootCertificate := &x509.Certificate{ SerialNumber: big.NewInt(2023), Subject: pkix.Name{ Organization: []string{"Your Organization"}, Country: []string{"Your Country"}, Province: []string{"Your Province"}, Locality: []string{"Your Locality"}, StreetAddress: []string{"Your Street Address"}, PostalCode: []string{"Your Postal Code"}, }, NotBefore: time.Now(), NotAfter: time.Now().AddDate(10, 0, 0), IsCA: true, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, BasicConstraintsValid: true, } rootCertificateBytes, err := x509.CreateCertificate(rand.Reader, x509RootCertificate, x509RootCertificate, &privateKey.PublicKey, privateKey) if err != nil { panic(err) } rootCertificate, err := x509.ParseCertificate(rootCertificateBytes) if err != nil { panic(err) } roots := x509.NewCertPool() roots.AddCert(rootCertificate) certificateChain, err := rootCertificate.Verify(x509.VerifyOptions{ Roots: roots, }) if err != nil { panic(err) } // Third step outputFile, err := os.Create("output.pdf") if err != nil { panic(err) } defer func(outputFile *os.File) { err = outputFile.Close() if err != nil { log.Println(err) } fmt.Println("output file closed") }(outputFile) inputFile, err := os.Open("input.pdf") if err != nil { panic(err) } defer func(inputFile *os.File) { err = inputFile.Close() if err != nil { log.Println(err) } fmt.Println("input file closed") }(inputFile) fileInfo, err := inputFile.Stat() if err != nil { panic(err) } size := fileInfo.Size() pdfReader, err := pdf.NewReader(inputFile, size) if err != nil { panic(err) } // Fourth step err = sign.Sign(inputFile, outputFile, pdfReader, size, sign.SignData{ Signature: sign.SignDataSignature{ Info: sign.SignDataSignatureInfo{ Name: "Your name", Location: "Your location", Reason: "Your reason", ContactInfo: "Your contact info", Date: time.Now().Local(), }, CertType: sign.CertificationSignature, DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms, }, Signer: privateKey, // crypto.Signer DigestAlgorithm: crypto.SHA256, // hash algorithm for the digest creation Certificate: rootCertificate, // x509.Certificate CertificateChains: certificateChain, // x509.Certificate.Verify() TSA: sign.TSA{ URL: "", 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 { log.Println(err) } else { log.Println("pdf signed") } }
结果:
go run main.go 2023/12/01 21:53:37 pdf signed input file closed output file closed
위 내용은 digitalorus/pdfsign을 사용하여 Go(Golang)에서 PDF 파일에 서명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!