Skip to content

Getting started

This page adds the module to a project, signs and verifies a message and encrypts content for a recipient certificate.

Install

go get github.com/misiektoja/go-pkcs7

The module needs Go 1.27.3 or newer and has no dependencies outside the standard library. The package is imported as pkcs7:

import "github.com/misiektoja/go-pkcs7"

The API may still change before v1.0.0, as the Compatibility policy describes.

Sign and verify

NewSignedData starts a message over the content. AddSigner signs it with the signer certificate cert and its private key key, an RSA or ECDSA crypto.Signer. Finish returns the encoded message:

sd, err := pkcs7.NewSignedData([]byte("hello, CMS"))
if err != nil {
    log.Fatal(err)
}
if err := sd.AddSigner(cert, key, pkcs7.SignerInfoConfig{}); err != nil {
    log.Fatal(err)
}
signed, err := sd.Finish()
if err != nil {
    log.Fatal(err)
}

The receiver parses the message and verifies it against the CA certificate it trusts:

p7, err := pkcs7.Parse(signed)
if err != nil {
    log.Fatal(err)
}
roots := x509.NewCertPool()
roots.AddCert(caCert)
if err := p7.Verify(pkcs7.VerifyOptions{Roots: roots}); err != nil {
    log.Fatal(err)
}
fmt.Printf("%s\n", p7.Content)

Verify checks the message digest, the signed attributes and the signature of every signer. With Roots set it also builds a chain from each signer certificate to one of the roots. Without Roots it checks the signatures only, so the caller must decide whether to trust the signer. Verification covers the options.

Encrypt and decrypt

Encrypt creates an EnvelopedData message for one or more RSA recipient certificates:

enveloped, err := pkcs7.Encrypt([]byte("for the recipient only"), []*x509.Certificate{recipientCert}, pkcs7.EncryptOptions{
    ContentEncryption: pkcs7.AES256CBC,
    KeyEncryption:     pkcs7.RSAOAEP,
})
if err != nil {
    log.Fatal(err)
}

The recipient decrypts it with its certificate and private key:

p7, err := pkcs7.Parse(enveloped)
if err != nil {
    log.Fatal(err)
}
plaintext, err := p7.Decrypt(recipientCert, recipientKey, pkcs7.DecryptOptions{})
if err != nil {
    log.Fatal(err)
}
fmt.Printf("%s\n", plaintext)

The defaults are AES-128-CBC and PKCS #1 v1.5 key transport, which SCEP peers expect. This example selects AES-256-CBC and RSAES-OAEP instead. Encryption and decryption explains the choices.

Run the examples

Apart from the import line above, the Go listings on this site come from example_test.go in the repository, where each one runs as a Go example and checks its output. Run them from a clone:

go test -run Example -v .

Next steps