{"id":166,"date":"2016-03-26T06:33:59","date_gmt":"2016-03-25T20:33:59","guid":{"rendered":"http:\/\/blog.wingsofhermes.org\/?p=166"},"modified":"2016-03-26T06:33:59","modified_gmt":"2016-03-25T20:33:59","slug":"pkcs8-files-and-windows-crypto-api-2","status":"publish","type":"post","link":"https:\/\/blog.wingsofhermes.org\/?p=166","title":{"rendered":"PKCS8 files and Windows Crypto API"},"content":{"rendered":"<p>Parts of the Windows Crypto API are quite well documented (particularly the original CAPI stuff).&nbsp; Other parts&#8230;..  <\/p>\n<p>I&#8217;ve been trying to get PKCS8 files working between OpenSSL and Windows.&nbsp; The Import\/Export on Windows is so badly documented I eventually resorted to ASN.1 decodes and header file trawls to find what I needed.  <\/p>\n<p>Anyway &#8211; if you need a password encrypted (using PBE) PKCS8 file that Windows can read, the best you&#8217;ll get is PBE-SHA1-3DES.&nbsp; So once you&#8217;ve generated your RSA key (let&#8217;s call it rsa.key) then you need to run openssl as follows:  <\/p>\n<p><code><em>openssl pkcs8 \u2013in .\/rsa.key \u2013topk8 \u2013outform DER \u2013out .\/key.pk8 \u2013v1 PBE-SHA1-3DES<\/em><\/code>  <\/p>\n<p>If you don\u2019t want to have a password \u2013 use <font face=\"Courier New\"><em>\u2013nocrypt<\/em><\/font><\/p>\n<p>Generating something that can go back the other way is just plain difficult.<\/p>\n<p>You need to use NCryptExportKey (BCryptExportKey doesn\u2019t have the capability).&nbsp; You also need to specify the algorithm OID, parameters and password in the export parameters.<\/p>\n<p>Some code to demonstrate.&nbsp; It\u2019s messy and it probably won\u2019t compile immediately as I\u2019ve just done a cut and paste \u2013 but hopefully it will be useful to someone.<\/p>\n<p><code>NCryptBufferDesc params, *pparams;<br \/>NCryptBuffer buffers[3];<br \/>DWORD pkcs8_blob_sz;<br \/>unsigned char * pkcs8_blob;<br \/>CRYPT_PKCS12_PBE_PARAMS * pbe_params;<br \/>unsigned char * salt;<\/p>\n<p>\/\/ Generate the parameters<br \/>pbe_params = (CRYPT_PKCS12_PBE_PARAMS *)malloc(sizeof(CRYPT_PKCS12_PBE_PARAMS) + 8);<br \/>memset(pbe_params, 0, sizeof(CRYPT_PKCS12_PBE_PARAMS) + 8);<br \/>salt = (unsigned char *) pbe_params + sizeof(CRYPT_PKCS12_PBE_PARAMS);<\/p>\n<p>\/\/ First some random for the salt<br \/>if (!NT_SUCCESS(BCryptGenRandom(amp-&gt;amp_bcrypt_rng, salt, 8, 0)))<br \/>{<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/* ERROR STUFF HERE *\/<br \/>}<\/p>\n<p>\/\/ Now the params<br \/>pbe_params-&gt;cbSalt = 8;<br \/>pbe_params-&gt;iIterations = 2048;<\/p>\n<p>buffers[2].BufferType = NCRYPTBUFFER_PKCS_ALG_PARAM;<br \/>buffers[2].cbBuffer = sizeof(CRYPT_PKCS12_PBE_PARAMS) + 8;<br \/>buffers[2].pvBuffer = pbe_params;<\/p>\n<p>buffers[1].BufferType = NCRYPTBUFFER_PKCS_ALG_OID;<br \/>buffers[1].pvBuffer = szOID_PKCS_12_pbeWithSHA1And3KeyTripleDES;<br \/>buffers[1].cbBuffer = strlen(szOID_PKCS_12_pbeWithSHA1And3KeyTripleDES) + 1; \/\/ Terminator needed<\/p>\n<p>buffers[0].BufferType = NCRYPTBUFFER_PKCS_SECRET;<br \/>buffers[0].pvBuffer = L\u201dPASSWORD\u201d; \/\/ Yes you need to replace this :)<br \/>buffers[0].cbBuffer = 12; \/* Include bytes for the wchar terminator *\/<\/p>\n<p>params.cBuffers = 3;<br \/>params.pBuffers = buffers;<br \/>params.ulVersion = NCRYPTBUFFER_VERSION;<\/p>\n<p>pparams = &amp;params;<\/p>\n<p>\/* Do the export *\/<br \/>if (NCryptExportKey(ncrypt_master_key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pparams, NULL, 0, &amp;pkcs8_blob_sz, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)<br \/>{<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/* ERROR CODE HERE *\/<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return AUTHME_ERR_CRYPTO_OPERATION;<br \/>}<\/p>\n<p>pkcs8_blob = (unsigned char *)malloc(pkcs8_blob_sz);<br \/>if (NCryptExportKey(ncrypt_master_key, 0, NCRYPT_PKCS8_PRIVATE_KEY_BLOB,<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pparams, pkcs8_blob, pkcs8_blob_sz, &amp;pkcs8_blob_sz, NCRYPT_SILENT_FLAG) != ERROR_SUCCESS)<br \/>{<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \/* ERROR CODE HERE *\/<\/p>\n<p>}<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Parts of the Windows Crypto API are quite well documented (particularly the original CAPI stuff).&nbsp; Other parts&#8230;.. I&#8217;ve been trying to get PKCS8 files working between OpenSSL and Windows.&nbsp; The Import\/Export on Windows is so badly documented I eventually resorted to ASN.1 decodes and header file trawls to find what I needed. Anyway &#8211; if&hellip; <span class=\"clear\"><\/span><a href=\"https:\/\/blog.wingsofhermes.org\/?p=166\" class=\"more-link read-more\" rel=\"bookmark\">Continue Reading <span class=\"screen-reader-text\">PKCS8 files and Windows Crypto API<\/span><i class=\"fa fa-arrow-right\"><\/i><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[13,4,15],"tags":[12,30,27,29],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pX0hd-2G","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/posts\/166"}],"collection":[{"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=166"}],"version-history":[{"count":4,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":170,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=\/wp\/v2\/posts\/166\/revisions\/170"}],"wp:attachment":[{"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.wingsofhermes.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}