I'm trying to output the original base64 form of an imported RSA public key using Windows CryptoAPI functions. Using CryptBinaryToString with the CRYPT_STRING_BASE64HEADER flag, the output header reads "BEGIN CERTIFICATE" instead of expected "BEGIN PUBLIC KEY".
(EDIT: I didn't highlight this part of my problem) Furthermore, the resulting public key appears to be different than the original.
Will this become problematic if I were to export the output and reimport it? If so, what am I doing wrong?
Here's how the public key was imported.
Public key is stored in file pubkey.pem in the following PEM format:
-----BEGIN PUBLIC KEY-----
[REDACTED]
-----END PUBLIC KEY-----
File is read into a buffer with CreateFile/ReadFile. PEM converted to binary using CryptStringToBinaryA. Binary is decoded to X509_PUBLIC_KEY_INFO using CryptDecodeObjectEx. PubKeyInfo struct is decoded to RSA_CSP_PUBLICKEYBLOB (same function as above).
This part works just fine (can import the key and encrypt data with CryptImportKey, CryptEncrypt, etc).
Here's the code that I've put together to try and bring the raw blob back to base64 PEM format. I've removed most error-checking to save headaches.
pbTmp and cbTmp are the temp buffer to hold output and size respectively. pBinaryKey is the raw public key blob (imported from earlier) pBuffer is the output buffer (assumed to be the correct size) ulDataLen is the output buffer size
CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, NULL, &cbTmp)
pbTmp = malloc(cbTmp);
CryptEncodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB, pBinaryKey, 0, NULL, pbTmp, &cbTmp)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, NULL, &ulDataLen)
CryptBinaryToStringA(pbTmp, cbTmp, CRYPT_STRING_BASE64HEADER, pBuffer, &ulDataLen)
The resulting buffer ends up with this:
-----BEGIN CERTIFICATE-----
[REDACTED; DIFFERENT FROM ORIGINAL PUBLIC KEY]
-----END CERTIFICATE-----