Microsoft CryptoAPI: how to convert PUBLICKEYBLOB to DER/PEM?

折月煮酒 提交于 2019-12-04 06:52:16

问题


I have a generated RSA key pair stored as PRIVATEKEYBLOB and PUBLICKEYBLOB, and I need to be able to convert these keys to DER or PEM formats so I could use it in PHP or Python. I figured out that I could use CryptEncodeObject function to convert my PRIVATEKEYBLOB to DER. In order to do that I need to use PKCS_RSA_PRIVATE_KEY encoding flag. But I couldn't find any clue on how to convert PUBLICKEYBLOB to DER.

Here is my code for PRIVATEKEYBLOB convertion:

LPCSTR type = PKCS_RSA_PRIVATE_KEY;
DWORD  encd = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;

DWORD dlen = 0;
if(!CryptEncodeObject(encd, type, key, null, &dlen))
{ LOG_ERROR(); return false; }

// Buffer allocation (der variable)

if(!CryptEncodeObject(encd, type, key, der, &dlen))
{ LOG_ERROR(); return false; }

I test my keys by comparing them to the output of openssl tool:

openssl rsa -pubin -inform MS\ PUBLICKEYBLOB -in pub.ms -outform DER -out pub.der
openssl rsa -inform MS\ PRIVATEKEYBLOB -in pri.ms -outform DER -out pri.der

ADDED: I tried RSA_CSP_PUBLICKEYBLOB with X509_ASN_ENCODING, but the result is different to the output of openssl tool, and the key import failes. The openssl's exported DER is 25 bytes longer, and only first 3 bytes are equal in both keys. Here is the picture of key comparison:

If we look closely at this picture, we can see that openssl's key version has some kind of additional 24 bytes header after the 3rd byte. Haven't figured out what is it as of yet, but if I concatinate this hardcoded header with the output I get from CryptEncodeObject with RSA_CSP_PUBLICKEYBLOB it all works fine. Not sure if that header is always the same or not though.


回答1:


Use RSA_CSP_PUBLICKEYBLOB as documented in https://msdn.microsoft.com/en-us/library/windows/desktop/aa378145(v=vs.85).aspx




回答2:


I struggled with PUBLICKEYBLOB -> PEM/DER formats until I found a post about pulling one from a smart card and converting it. The gist of it is, MS PUBLICKEYBLOB needs to have the first 32 bytes removed, then reverse the order and add 02 03 01 00 01 to the end. That will give you DER format. You can then base64 encode to get PEM and then add the requisite begin/end public key lines.

You can refer to the original post for background.



来源:https://stackoverflow.com/questions/36258135/microsoft-cryptoapi-how-to-convert-publickeyblob-to-der-pem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!