OpenSSL CMS Binary Signatures


Using openssl cms (cryptographic message syntax) to sign data (not email)

cms.sh is a shell script for signing arbitrary data, with the resulting PKCS7 signature and data concatenated into a single output file. It can also verify the signed data while optionally extracting the data to a file or stdout, or extract without verifying.

In an application for secure distribution of data files, combining the signature and data in a single file can help prevent the signature from being lost or ignored, as it might be with a detached signature. A signed file can also be attached and extracted from email, independent of any SMIME signature on the mail, and does not rely on the client mail system to verify the signature.

Usage:   cms.sh [config_options] [-q] -s|-v|-e|-i|-I infile [outfile|-]

-q   quiet, no verbose output
-s   sign, signed data is {infile_basename}.cms in current directory unless otherwise specified by outfile
-v   verify, no data extracted unless otherwise specified by outfile
-e   extract data to stdout unless otherwise specified by outfile
-i   info, display signature date and signer certificate issuer and subject
-I   display the entire pkcs7 structure

config_options:
  -CAfile cafile # used for signing and verifying, default = demoCA/cacert.pem
  -signer signer_cert # used for signing, default = testcert.pem
  -inkey signer_key # used for signing, default = testkey.pem

temporary $sig file is created in current directory and removed at end

signed data is signature concatenated with data:   cat "$sig" "$data"
signature is created using:   openssl cms -sign -binary
signature is verified using:   openssl cms -verify -binary
signature is extracted using:   openssl cms -cmsout
data is extracted using:   tail -c "+$((siglen+1))"

Notes

To create demo CA and certificate for testing:

  CA.pl -newca; CA.pl -newreq; CA.pl -sign; mv newkey.pem testkey.pem; mv newcert.pem testcert.pem

To decrypt private key:   openssl pkey < testkey.pem > j; mv j testkey.pem

Examples

$ echo hi > data

$ ./cms.sh -s data
Signing data -> data.sig
Checking data.sig
Verifying signature
CMS Verification successful
Writing cms to data.cms
Removing data.sig

$ ./cms.sh -q -s data

$ ./cms.sh -v data.cms
Extracting data.sig
Verifying signature
CMS Verification successful
Removing data.sig

$ ./cms.sh -v data.cms -
Extracting data.sig
Verifying signature and writing data to stdout
hi
CMS Verification successful
Removing data.sig

$ ./cms.sh -v data.cms d2
Extracting data.sig
Verifying signature and writing data to d2
CMS Verification successful
Removing data.sig

$ cat d2
hi

$ ./cms.sh -e data.cms
Extracting data.sig
Writing data to stdout
WARNING: not checking signature
hi
Removing data.sig

$ ./cms.sh -i data.cms
UTCTIME:May 15 00:12:48 2025 GMT
issuer: C=US, ST=PA, O=Demo CA, CN=Demo CA
subject: C=US, ST=PA, O=Testing, CN=Test Cert

$ ./cms.sh -CAfile SectigoCA.pem -signer RPcert.pem -inkey RPkey.pem -s data
Signing data -> data.sig
Enter pass phrase for RPkey.pem:
Checking data.sig
Verifying signature
CMS Verification successful
Writing cms to data.cms
Removing data.sig

$ ./cms.sh -CAfile SectigoCA.pem -v data.cms
Extracting data.sig
Verifying signature
CMS Verification successful
Removing data.sig

$ ./cms.sh -i data.cms
UTCTIME:May 15 00:13:57 2025 GMT
issuer: C=GB, O=Sectigo Limited, CN=Sectigo Public Email Protection CA R36
subject: emailAddress=perry@misty.com

$ tar cvhzf pem.tar.gz *.pem
RPcert.pem
RPkey.pem
SectigoCA.pem
testcert.pem
testkey.pem

$ ./cms.sh -s pem.tar.gz
Signing pem.tar.gz -> pem.tar.gz.sig
Checking pem.tar.gz.sig
Verifying signature
CMS Verification successful
Writing cms to pem.tar.gz.cms
Removing pem.tar.gz.sig

$ ./cms.sh -v pem.tar.gz.cms - | tar tvzf -
Extracting pem.tar.gz.sig
Verifying signature and writing data to stdout
CMS Verification successful
Removing pem.tar.gz.sig
-rw-r--r-- perry/perry    1989 2025-05-11 11:15 RPcert.pem
-rw------- perry/perry    1854 2025-05-11 11:10 RPkey.pem
-rw-r--r-- perry/perry    7238 2025-05-11 11:18 SectigoCA.pem
-rw-r--r-- perry/perry    4276 2025-05-13 05:33 testcert.pem
-rw-r--r-- perry/perry    1704 2025-05-13 05:34 testkey.pem

$ ./cms.sh -I pem.tar.gz.cms > pem.I.txt

$