PKCS7_ENCRYPT(3ossl)
π PKCS7_ENCRYPT (3ossl) β bestie's guide to sealing the tea π
okay so this is the OpenSSL manpage for PKCS7_ENCRYPT, part of the OpenSSL docs (yes, that OpenSSL), and we're about to make envelopedData make sense. sit down, hydrate, let's go π«Ά
β¨ NAME β¨
PKCS7_encrypt_ex, PKCS7_encrypt β create a PKCS#7 envelopedData structure. that's it. that's the job. π
πΈ SYNOPSIS πΈ
#include <openssl/pkcs7.h>
PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, int flags,
OSSL_LIB_CTX *libctx, const char *propq);
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
int flags);
two functions, one glow-up. the _ex one is the newer, more customizable sibling π
π DESCRIPTION π
PKCS7_encrypt_ex() creates and returns a PKCS#7 envelopedData structure. iconic behavior fr.
here's the cast of characters:
certsβ a list of recipient certificates πinβ the content you want to encrypt πcipherβ the symmetric cipher to use πflagsβ an optional set of flags π©libctxandpropqβ the library context and property query, used when retrieving algorithms from providers β¨
big important note: only RSA keys are supported in PKCS#7 and envelopedData, so every recipient certificate you hand this function must contain an RSA public key. they do not have to be signed using the RSA algorithm though β so like, the signing can be whatever, but the key itself has to be RSA. no exceptions bestie π
EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use, because basically every client out there supports it. it's giving "safe bet, always invited to the party."
now, some old "export grade" clients (vintage, retro, lowkey ancient) may only support weak encryption using 40 or 64 bit RC2. you can serve those by passing EVP_rc2_40_cbc() and EVP_rc2_64_cbc() respectively. yes they're weak. yes they're still in the API. we don't gatekeep history π
the algorithm you pass in the cipher parameter must support ASN1 encoding of its parameters. non-negotiable, it's the rules.
a lot of browsers ship a "sign and encrypt" option, which is honestly just an S/MIME envelopedData holding an S/MIME signed message inside. very nesting-doll of them πͺ. you can make one of these super easily: store the S/MIME signed message in a memory BIO and pass it to PKCS7_encrypt().
π© the flags you can pass in flags π©
- if the
PKCS7_TEXTflag is set, MIME headers for typetext/plainget prepended to the data. cute little header moment. - normally the supplied content gets translated into MIME canonical format (as required by the S/MIME specifications). if
PKCS7_BINARYis set, no translation occurs. use this one if your supplied data is in binary format, otherwise the translation will corrupt it π β and heads up, ifPKCS7_BINARYis set, thenPKCS7_TEXTis ignored. sorry text, binary ate π - if the
PKCS7_STREAMflag is set, a partial PKCS7 structure is output, suitable for streaming I/O: no data is read from the BIOin. streaming girlies rise π
β οΈ if the flag PKCS7_STREAM is set, the returned PKCS7 structure is not complete, and outputting its contents via a function that does not properly finalize the PKCS7 structure will give unpredictable results. do not play with this one, it will not play nice back π
several functions do finalize the structure, including:
SMIME_write_PKCS7()i2d_PKCS7_bio_stream()PEM_write_bio_PKCS7_stream()
alternatively, you can finalize it by obtaining the streaming ASN1 BIO directly using BIO_new_PKCS7(). options, options, we love choices β¨
lastly: PKCS7_encrypt() is basically PKCS7_encrypt_ex() but it uses default values of NULL for the library context libctx and the property query propq. the chill, no-extra-args version π¦
π«Ά RETURN VALUES π«Ά
PKCS7_encrypt_ex() and PKCS7_encrypt() return either a PKCS7 structure, or NULL if an error occurred. if it's NULL, you can go get the error from ERR_get_error(3). don't just sit there wondering what went wrong, the info is right there bestie π₯Ί
π SEE ALSO π
(the whole decrypt-and-encrypt duo, a matched set, obsessed π)
π HISTORY π
- the function
PKCS7_encrypt_ex()was added in OpenSSL 3.0. - the
PKCS7_STREAMflag was added in OpenSSL 1.0.0.
ancient lore, but we respect it ποΈ
π COPYRIGHT π
Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
and that's the whole page, no cap π β this was PKCS7_ENCRYPT(3ossl) from OpenSSL 3.5.9, dated 2026-09-29. go forth and encrypt responsibly, my love, and remember: RSA keys only, PKCS7_BINARY for binaries, and always finalize your streams π
β¨π
π¦ where this page comes from
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms