PKCS5_PBE_KEYIVGEN(3SSL)
π PKCS5_PBE_KEYIVGEN β¨ (that's the 3SSL manual, bestie)
okay so. this is the OpenSSL page about PKCS#5 password-based encryption routines β key derivation and AlgorithmIdentifier building. it's a lot of functions but honestly? they're all your friends. let's go π
πΈ NAME πΈ
PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex, PKCS5_pbe2_set, PKCS5_pbe2_set_iv, PKCS5_pbe2_set_iv_ex, PKCS5_pbe_set, PKCS5_pbe_set_ex, PKCS5_pbe2_set_scrypt, PKCS5_pbe_set0_algor, PKCS5_pbe_set0_algor_ex, PKCS5_v2_PBE_keyivgen, PKCS5_v2_PBE_keyivgen_ex, PKCS5_v2_scrypt_keyivgen, PKCS5_v2_scrypt_keyivgen_ex, PKCS5_pbkdf2_set, PKCS5_pbkdf2_set_ex, EVP_PBE_scrypt, EVP_PBE_scrypt_ex β PKCS#5 Password based encryption routines π«Ά
β¨ SYNOPSIS β¨
first batch lives in <openssl/evp.h>:
#include <openssl/evp.h>
int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de);
int PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de, OSSL_LIB_CTX *libctx,
const char *propq);
int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de);
int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
ASN1_TYPE *param, const EVP_CIPHER *cipher,
const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
int EVP_PBE_scrypt(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen);
int EVP_PBE_scrypt_ex(const char *pass, size_t passlen,
const unsigned char *salt, size_t saltlen,
uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
unsigned char *key, size_t keylen,
OSSL_LIB_CTX *ctx, const char *propq);
int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de);
int PKCS5_v2_scrypt_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass,
int passlen, ASN1_TYPE *param,
const EVP_CIPHER *c, const EVP_MD *md, int en_de,
OSSL_LIB_CTX *libctx, const char *propq);
and then the <openssl/x509.h> girlies:
#include <openssl/x509.h>
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen);
int PKCS5_pbe_set0_algor_ex(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
const unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe_set_ex(int alg, int iter,
const unsigned char *salt, int saltlen,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen);
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid);
X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid,
OSSL_LIB_CTX *libctx);
X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
const unsigned char *salt, int saltlen,
unsigned char *aiv, uint64_t N, uint64_t r,
uint64_t p);
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen);
X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen,
int prf_nid, int keylen,
OSSL_LIB_CTX *libctx);
π DESCRIPTION π
π Key Derivation π
so PKCS5_PBE_keyivgen() and PKCS5_PBE_keyivgen_ex() take a password pass of length passlen, some parameters param, and a message digest function md_type, and they do a key derivation, per PKCS#5 PBES1. then that resulting key initialises the cipher context ctx with a cipher cipher β encryption when en_de=1, decryption when en_de=0. pick your fighter π
pass is optional, bestie β it can literally be NULL. and if passlen is -1, the function just calls strlen() to figure out the length of pass itself. self-sufficient queen.
PKCS5_v2_PBE_keyivgen() and PKCS5_v2_PBE_keyivgen_ex() are basically the same vibe as above, fr fr β except they use PKCS#5 PBES2 as the encryption algorithm and take the params you hand them.
PKCS5_v2_scrypt_keyivgen() and PKCS5_v2_scrypt_keyivgen_ex() do the encryption thing but with SCRYPT handling the key derivation part. scrypt girlies rise π§
salt is the salt used for the derivation, and it has length saltlen. β οΈ if the salt is NULL, then saltlen must be 0. and no, the function will not try to measure the salt's length β it does not assume the salt is NUL-terminated, so don't roll up expecting it to.
iter is the iteration count and should be greater than or equal to 1. RFC 2898 suggests using at least 1000 iterations (yes, really, 1000 minimum, we love a security queen). and any iter less than 1 gets treated as a single iteration. so it just quietly rounds you up. no cap.
digest is the message digest function used in the derivation.
aiv is the initialisation vector (IV) for the encryption algorithm. if aiv is NULL, a random IV gets generated for you. little treat π
prf_nid is the numeric identifier (NID) for the pseudo-random function used with PBKDF2. if prf_nid isn't specified β like when prf_nid is set to 0 β a default PRF is used, and that default is currently SHA-256 (NID_hmacWithSHA256). miss default does the most.
all the functions ending in _ex() take the optional parameters libctx and propq, which are used to select the appropriate algorithm implementations. iykyk π
π·οΈ Algorithm Identifier Creation π·οΈ
PKCS5_pbe_set(), PKCS5_pbe_set_ex(), PKCS5_pbe2_set(), PKCS5_pbe2_set_iv(), PKCS5_pbe2_set_iv_ex() and PKCS5_pbe2_set_scrypt() generate an X509_ALGOR object. that object represents an AlgorithmIdentifier containing the algorithm OID and its associated parameters for the PBE algorithm. basically these functions encode the key derivation parameters (salt, iteration count, the whole situation) and the encryption parameters (like the IV) into the ASN.1 structure. it's giving structure ποΈβ¨
PKCS5_pbkdf2_set() and PKCS5_pbkdf2_set_ex() generate an X509_ALGOR object too β one representing an AlgorithmIdentifier with the algorithm OID and associated parameters for the PBKDF2 algorithm.
PKCS5_pbe_set0_algor() and PKCS5_pbe_set0_algor_ex() set the PBE algorithm OID and parameters into the X509_ALGOR you supply. drop it in, no copy.
and now, the salt lore π§ if salt is NULL, then saltlen specifies the size in bytes of the random salt to generate. if saltlen is 0, a default size is used:
- for PBE related functions like
PKCS5_pbe_set_ex(), the default salt length is 8 bytes - for PBE2 related functions that use PBKDF2 β like
PKCS5_pbkdf2_set(),PKCS5_pbe2_set_scrypt()andPKCS5_pbe2_set()β the default salt length is 16 bytes
π NOTES π
the *_keyivgen() functions are typically used in PKCS#12 to encrypt objects.
and listen: these functions make no assumption about the password you give them. it just gets treated as a byte sequence. that's it. that's the whole relationship. no character encoding opinions, no judgement π
π«Ά RETURN VALUES π«Ά
these ones return 1 for success and 0 if an error occurs:
PKCS5_PBE_keyivgen()PKCS5_v2_PBE_keyivgen()PKCS5_v2_PBE_keyivgen_ex()PKCS5_v2_scrypt_keyivgen()PKCS5_v2_scrypt_keyivgen_ex()PKCS5_pbe_set0_algor()PKCS5_pbe_set0_algor_ex()
and these ones return an X509_ALGOR object β or NULL if something goes wrong:
PKCS5_pbe_set()PKCS5_pbe_set_ex()PKCS5_pbe2_set()PKCS5_pbe2_set_iv()PKCS5_pbe2_set_iv_ex()PKCS5_pbe2_set_scrypt()PKCS5_pbkdf2_set()PKCS5_pbkdf2_set_ex()
always check your returns, bestie. NULL is not a personality π
π CONFORMING TO π
IETF RFC 8018 (<https://tools.ietf.org/html/rfc8018>) β canon. periodt.
π SEE ALSO π
π°οΈ HISTORY π°οΈ
these ones were added in OpenSSL 3.0:
PKCS5_v2_PBE_keyivgen_ex()EVP_PBE_scrypt_ex()PKCS5_v2_scrypt_keyivgen_ex()PKCS5_pbe_set0_algor_ex()PKCS5_pbe_set_ex()PKCS5_pbe2_set_iv_ex()PKCS5_pbkdf2_set_ex()
from OpenSSL 3.0, the PBKDF1 algorithm used in PKCS5_PBE_keyivgen() and PKCS5_PBE_keyivgen_ex() has been moved to the legacy provider as an EVP_KDF. legacy era π
in OpenSSL 3.2, the default salt length changed from 8 bytes to 16 bytes for PBE2 related functions such as PKCS5_pbe2_set(). this is required for PBKDF2 FIPS compliance. glow-up for compliance reasons β¨
Β©οΈ COPYRIGHT Β©οΈ
Copyright 2021-2026 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, bestie π«Ά this was OpenSSL 4.0.3, dated 2026-09-29, and it's the PKCS5_PBE_KEYIVGEN(3SSL) manual β go forth and derive those keys responsibly, mwah ππ
π
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms