D2I_RSAPUBLICKEY(3)
π D2I_RSAPUBLICKEY(3) β bestie edition π
okay so this is the D2I_RSAPUBLICKEY(3) page from the libcrypto girlies, and it's literally all about turning RSA keys and parameters into DER bytes and back again. it's giving β¨serializationβ¨ but make it cryptography. buckle up, we have a LOT of functions to get through and i'm not skipping a single one π
πΈ NAME πΈ
d2i_RSAPublicKey, i2d_RSAPublicKey, d2i_RSAPrivateKey, i2d_RSAPrivateKey, d2i_Netscape_RSA, i2d_Netscape_RSA, d2i_RSA_PSS_PARAMS, i2d_RSA_PSS_PARAMS, d2i_RSAPublicKey_bio, d2i_RSAPublicKey_fp, i2d_RSAPublicKey_bio, i2d_RSAPublicKey_fp, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey_fp, d2i_RSA_PUBKEY, i2d_RSA_PUBKEY, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY_fp β decode and encode RSA keys and parameters π¦
(yes that's a lot of names, no i will not be abbreviating, every single one is here and accounted for. periodt.)
β¨ SYNOPSIS β¨
first up, the library is libcrypto, and you're gonna want this include:
#include <openssl/rsa.h>
and then, in order, because the order is iconic:
RSA *
d2i_RSAPublicKey(RSA **val_out, const unsigned char **der_in,
long length);
int
i2d_RSAPublicKey(RSA *val_in, unsigned char **der_out);
RSA *
d2i_RSAPrivateKey(RSA **val_out, const unsigned char **der_in,
long length);
int
i2d_RSAPrivateKey(RSA *val_in, unsigned char **der_out);
RSA *
d2i_Netscape_RSA(RSA **val_out, const unsigned char **der_in,
long length, int (*cb)());
int
i2d_Netscape_RSA(RSA *val_in, unsigned char **der_out, int (*cb)());
RSA_PSS_PARAMS *
d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **val_out,
const unsigned char **der_in, long length);
int
i2d_RSA_PSS_PARAMS(RSA_PSS_PARAMS *val_in, unsigned char **der_out);
then bestie switches headers on us β this is a whole new vibe:
#include <openssl/x509.h>
RSA *
d2i_RSAPublicKey_bio(BIO *in_bio, RSA **val_out);
RSA *
d2i_RSAPublicKey_fp(FILE *in_fp, RSA **val_out);
int
i2d_RSAPublicKey_bio(BIO *out_bio, RSA *val_in);
int
i2d_RSAPublicKey_fp(FILE *out_fp, RSA *val_in);
RSA *
d2i_RSAPrivateKey_bio(BIO *in_bio, RSA **val_out);
RSA *
d2i_RSAPrivateKey_fp(FILE *in_fp, RSA **val_out);
int
i2d_RSAPrivateKey_bio(BIO *out_bio, RSA *val_in);
int
i2d_RSAPrivateKey_fp(FILE *out_fp, RSA *val_in);
RSA *
d2i_RSA_PUBKEY(RSA **val_out, const unsigned char **der_in,
long length);
int
i2d_RSA_PUBKEY(RSA *val_in, unsigned char **der_out);
RSA *
d2i_RSA_PUBKEY_bio(BIO *in_bio, RSA **val_out);
RSA *
d2i_RSA_PUBKEY_fp(FILE *in_fp, RSA **val_out);
int
i2d_RSA_PUBKEY_bio(BIO *out_bio, RSA *val_in);
int
i2d_RSA_PUBKEY_fp(FILE *out_fp, RSA *val_in);
π DESCRIPTION π
so! these functions decode and encode RSA private and public keys. π₯ for the nitty-gritty on the semantics, examples, caveats, and bugs, you go read ASN1_item_d2i(3) β that's the deep lore, i'm just the messenger.
π©· the public key ones
d2i_RSAPublicKey() and i2d_RSAPublicKey() decode and encode a PKCS#1 RSAPublicKey structure, which is defined in RFC 8017 appendix A.1.1. π
d2i_RSAPublicKey_bio(), d2i_RSAPublicKey_fp(), i2d_RSAPublicKey_bio(), and i2d_RSAPublicKey_fp() are basically the same thing, except they decode or encode using a BIO or FILE pointer. same energy, different plumbing π
π the private key ones
d2i_RSAPrivateKey() and i2d_RSAPrivateKey() decode and encode a PKCS#1 RSAPrivateKey structure defined in RFC 8017 appendix A.1.2. ποΈ
β οΈ heads up: the RSA structure passed to the private key encoding functions should have all the PKCS#1 private key components present. don't be out here passing half a key, it's not gonna slay.
π¨ also, and this is important, bestie: the data encoded by the private key functions is unencrypted and therefore offers no private key security. like, zero. none. it's just vibes and raw bytes. protect it yourself.
d2i_RSAPrivateKey_bio(), d2i_RSAPrivateKey_fp(), i2d_RSAPrivateKey_bio(), and i2d_RSAPrivateKey_fp() are similar except that they decode or encode using a BIO or FILE pointer. π«Ά
π΅ the Netscape ones (aka the ancient ones)
d2i_Netscape_RSA() and i2d_Netscape_RSA() decode and encode an RSA private key in NET format.
these functions are present to provide compatibility with certain very old software. π¦
π the NET format has some severe security weaknesses and should be avoided if possible. like, if you can avoid it, avoid it. this is not the moment for main character energy, this is the moment for a modern format.
π the PSS params ones
d2i_RSA_PSS_PARAMS() and i2d_RSA_PSS_PARAMS() decode and encode a PKCS#1 RSASSA-PSS-params structure defined in RFC 8017 appendix A.2.3, and documented in RSA_PSS_PARAMS_new(3). β¨
π the SubjectPublicKeyInfo ones
d2i_RSA_PUBKEY() and i2d_RSA_PUBKEY() decode and encode an RSA public key using an ASN.1 SubjectPublicKeyInfo structure defined in RFC 5280 section 4.1, and documented in X509_PUBKEY_new(3). π¦
d2i_RSA_PUBKEY_bio(), d2i_RSA_PUBKEY_fp(), i2d_RSA_PUBKEY_bio(), and i2d_RSA_PUBKEY_fp() are similar except that they decode or encode using a BIO or FILE pointer. same drill, different pointer types π
β RETURN VALUES β
okay so the decode girlies first:
d2i_RSAPublicKey(), d2i_RSAPublicKey_bio(), d2i_RSAPublicKey_fp(), d2i_RSAPrivateKey(), d2i_RSAPrivateKey_bio(), d2i_RSAPrivateKey_fp(), d2i_Netscape_RSA(), d2i_RSA_PUBKEY(), d2i_RSA_PUBKEY_bio(), and d2i_RSA_PUBKEY_fp() return a valid RSA object, or NULL if an error occurs. π
d2i_RSA_PSS_PARAMS() returns a valid RSA_PSS_PARAMS object, or NULL if an error occurs.
then the encode-into-buffer crowd:
i2d_RSAPublicKey(), i2d_RSAPrivateKey(), i2d_Netscape_RSA(), i2d_RSA_PSS_PARAMS(), and i2d_RSA_PUBKEY() return the number of bytes successfully encoded, or a negative value if an error occurs. π
and the bio/fp encoders:
i2d_RSAPublicKey_bio(), i2d_RSAPublicKey_fp(), i2d_RSAPrivateKey_bio(), i2d_RSAPrivateKey_fp(), i2d_RSA_PUBKEY_bio(), and i2d_RSA_PUBKEY_fp() return 1 for success or 0 if an error occurs. π―
π SEE ALSO π
go read these next, bestie, they're all linked up:
ASN1_item_d2i(3)EVP_PKEY_set1_RSA(3)PEM_write_RSAPrivateKey(3)RSA_new(3)RSA_PSS_PARAMS_new(3)X509_PUBKEY_new(3)
π STANDARDS π
- RFC 8017: PKCS #1: RSA Cryptography Specifications
- RFC 5280: Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, section 4.1: Basic Certificate Fields
π§ HISTORY π§
and now the lore drop π°οΈ:
d2i_RSAPublicKey(), i2d_RSAPublicKey(), d2i_RSAPrivateKey(), i2d_RSAPrivateKey(), d2i_RSAPrivateKey_fp(), i2d_RSAPrivateKey_fp(), d2i_Netscape_RSA(), and i2d_Netscape_RSA() first appeared in SSLeay 0.5.1.
d2i_RSAPrivateKey_bio() and i2d_RSAPrivateKey_bio() first appeared in SSLeay 0.6.0.
d2i_RSAPublicKey_bio(), d2i_RSAPublicKey_fp(), i2d_RSAPublicKey_bio(), and i2d_RSAPublicKey_fp() first appeared in SSLeay 0.8.1.
these functions have been available since OpenBSD 2.4. π
d2i_RSA_PUBKEY(), i2d_RSA_PUBKEY(), d2i_RSA_PUBKEY_bio(), d2i_RSA_PUBKEY_fp(), i2d_RSA_PUBKEY_bio(), and i2d_RSA_PUBKEY_fp() first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7. πΈ
d2i_RSA_PSS_PARAMS() and i2d_RSA_PSS_PARAMS() first appeared in OpenSSL 1.0.1 and have been available since OpenBSD 5.3. β¨
and that's the page!! π this particular printing came from Debian, dated June 8, 2025 β so if you're citing it, that's the tea π«Ά mwah, go forth and encode responsibly π
π¦ where this page comes from
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2000, 2002, 2003, 2009, 2016 The OpenSSL Project
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms