Convert keys to/from a M$ format

My client wants me to write a Cocoa code to


- generate a RSA key pair, and then convert it to Microsoft BCRYPT_RSAKEY_BLOB structure;

- convert the Microsoft BCRYPT_RSAKEY_BLOB structure to a RSA key pair useable to en/decrypt.


The BCRYPT_RSAKEY_BLOB structure is described at https://msdn.microsoft.com/en-us/library/windows/desktop/aa375531(v=vs.85).aspx


I went through the Security SecKey... APIs a zillion times, but I can't find a way to do that. Would be really grateful for any help.


I can generate the key pair all right; I can use it for en/decryption. But the only service to get the detailed key information I have found is SecKeyCopyAttributes, and, alas,

(a) I did not find a detailed description of the returned attributes;

(b) checking them in debugger, I can't see there those things the MS jokers want (like exponent, modulus, etc.)

(c) besides, I did not find a way to create a key pair based on the attributes, i.e., an inverse function to SecKeyCopyAttributes;

(d) and what's worse, I would need to support macOSen back to at least 10.10, and SecKeyCopyAttributes seems to be 10.12+.


I have tried to find another APIs for that, but in vain. Can anybody help? Thanks!

Accepted Answer

Apple’s security APIs typically work in terms of DER-encoded ASN.1 PKCS#1 data structures. For a private key this would be the

RSAPrivateKey
data structure, as defined Section 7.2 of RFC 2313.

To convert to

BCRYPT_RSAKEY_BLOB
you’d need to:
  1. Get the raw key bytes.

  2. Break apart the ASN.1 to get the required fields (

    modulus
    ,
    publicExponent
    ,
    prime1
    ,
    prime2
    ).
  3. Pack those into the

    BCRYPT_RSAKEY_BLOB
    data structure.

macOS has no code for step 3. You’re on your own there.

With regards step 1, you can do this trivially using

SecKeyCopyExternalRepresentation
. This is, alas, new on 10.12. On older platforms you’ll need to use one of the export routines in
<Security/SecImportExport.h>
(and these assume that the key is in a keychain, so if you’re not generating it in a keychain then you’ll need to do that as well).

With regards step 2, parsing ASN.1 is un-fun. On iOS-based you’d have to use your own library for this — one you either write or acquire — because iOS has no public ASN.1 APIs. macOS does have an ASN.1 API,

<Security/SecAsn1Coder.h>
, but it is not easy to use and the documentation is extremely sparse.

It’s a similar process for going in the other direction.

Honestly I think your best option is to push back on the client here. Presumably you’re interacting with a platform that has a full-featured crypto toolbox, and it’s very likely that that toolbox can import and export DER-encoded ASN.1 PKCS#1 private keys. Even if that’s not possible, virtually all platforms can deal with PEM, and that’s essentially a Base64 encoded form of the data you need.

ps Sorry about deleting an earlier version of this post. Just after posting it I noticed that

<Security/SecImportExport.h>
has an
kSecFormatBSAFE
option, and I was curious whether that was related to the “BCRYPT” format you’ll looking for. A quick test reveals that it is not.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Convert keys to/from a M$ format
 
 
Q