Вот пример приведенной выше цепочки команд openssl, преобразованной в вызовы API openssl, которые выводят результат base64 на экран.
Основные звонки
Существует множество способов выполнить одну и ту же работу, используя варианты API OPENSSL, описанных выше, в зависимости от вашей ситуации.
Ниже приведено использование C ++ OpenSSL C API. При необходимости вы можете легко удалить биты C ++.
template<typename T, typename D>
std::unique_ptr<T, D> make_handle(T* handle, D deleter)
{
return std::unique_ptr<T, D>{handle, deleter};
}
bool load_rsa_private_key_and_base64_sha256_hash_public_key()
{
// load rsa private key in PEM format
auto bio = make_handle(BIO_new_file("privatekey.pem", "rb"), BIO_free);
if(!bio) return false;
auto const key = make_handle(PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, (void*)("password")), EVP_PKEY_free);
bio.reset();
if(!key) return false;
// extract private key from loaded certificate
auto const rsa = EVP_PKEY_get0_RSA(key.get());
if (!rsa) return false;
// setup sha256 bio chain
auto const bmd = make_handle(BIO_new(BIO_f_md()), BIO_free);
if(!bmd) return false;
if (!BIO_set_md(bmd.get(), EVP_sha256())) return false;
auto const null_bio = make_handle(BIO_new(BIO_s_null()), BIO_free);
auto in = BIO_push(bmd.get(), null_bio.get());
// write RSA Public Key into DER format to the SHA256 digest BIO chain
i2d_RSA_PUBKEY_bio(in, rsa);
// extract the SHA256 digest
auto mdtmp = BIO_find_type(in, BIO_TYPE_MD);
if (!mdtmp) return false;
std::array<char, EVP_MAX_MD_SIZE> buffer;
auto const length = BIO_gets(mdtmp, buffer.data(), buffer.size());
if(length <= 0) return false;
// convert the digest to base64 and output to the stdio
auto const b64 = make_handle(BIO_new(BIO_f_base64()), BIO_free);
auto const bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
auto out = BIO_push(b64.get(), bio_out);
BIO_write(out, buffer.data(), length);
BIO_flush(out);
return true;
}