Skip to content

adippel/cms-encryption-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CMS Encryption in Go: Secure Data with OpenSSL and CGO

This project demonstrates how to perform CMS (Cryptographic Message Syntax) encryption in Go using OpenSSL’s libcrypto via CGO. It includes a simple command-line tool that encrypts a message for a recipient using their X.509 certificate, producing a .p7m CMS/PKCS#7 message.

📖 This is companion code for the blog post: CMS Encryption in Go: Secure Data with OpenSSL and CGO

Features

  • Encrypt messages using CMS and AES-GCM
  • X.509 certificate parsing and recipient management
  • PEM-formatted CMS output (.p7m)
  • OpenSSL error handling in Go
  • Wrapping C macros for CGO compatibility

Development setup

This example relies on CGO and the OpenSSL C libraries. CGO has support for pkg-config to correctly discover required paths for the compiler and linker. Ensure that the following is installed on your system:

  • pkg-config
  • openssl and its header files

Ensure OpenSSL >= 3.0 is installed on your system and can be discovered using pkg-config:

pkg-config --modversion openssl

A note for macOS users

macOS' native OpenSSL distribution cannot be symlinked due to restrictions on macOS. Install OpenSSL separatly for example using brew. To allow pkg-config to find the installation, ensure to set the following environment variable ( change path if your are not using brew):

export PKG_CONFIG_PATH="$(brew --prefix openssl)/lib/pkgconfig"

To test your installation, run and check the output that should be similar to the shown output:

pkg-config --cflags --libs openssl
-I/opt/homebrew/Cellar/openssl@3/3.4.1/include -L/opt/homebrew/Cellar/openssl@3/3.4.1/lib -lssl -lcrypto

Example

The main.go contains small CLI examples demonstrating the usage of the library. To start encrypting, generate a new EC key and a self-signed certificate as follows:

CMS_KEY=ec-private-key.pem                                                                            
CMS_CERT=ec-test-cert.pem

openssl req -new -newkey ec -pkeyopt group:prime256v1 -noenc -keyout $CMS_KEY \
        -out $CMS_CERT -outform PEM -x509 -days 365 \
        -subj "/O=alexdippel.de laboratory/OU=CMS Test laboratory/CN=test-recipient" \
        -addext keyUsage=critical,digitalSignature,keyAgreement

Then, we can encrypt the message for the certificate:

go run ./main.go -cert "$CMS_CERT" -out ./encrypted.p7m -message "Hello  Test"

The encrypted message is saved in the file encrypted.p7m. To view the CMS structure, use the following command:

openssl cms -cmsout -inform PEM -in ./encrypted.p7m -print

To decrypt the message with the corresponding private key, use the following command:

openssl cms -decrypt -in ./encrypted.p7m -inform PEM -recip $CMS_CERT -inkey $CMS_KEY

About

Go example for performing CMS encryption with OpenSSL using CGO. Companion code for the blog post “CMS Encryption in Go”.

Topics

Resources

License

Stars

Watchers

Forks

Languages