Hello,

I’m not very experienced in cryptography and related topics, ví it may be possible I’m overlooking something quite obvious. The straightforward question is: is it possible đồ sộ create OpenSSH compatible key pairs, lượt thích ssh-keyget utility does, using Security framework? Let’s say, I want đồ sộ vì thế the equivalent of the following terminal command:

ssh-keygen -t rsa -b 4096 -C “[email protected]"

I’m trying that with this simplified piece of code:

CFMutableDictionaryRef privAttrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(privAttrs, kSecAttrIsPermanent, kCFBooleanFalse); CFDictionarySetValue(privAttrs, kSecAttrLabel, CFSTR("[email protected]")); CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(attrs, kSecAttrKeyType, kSecAttrKeyTypeRSA); CFDictionarySetValue(attrs, kSecAttrKeySizeInBits, CFSTR("4096")); CFDictionarySetValue(attrs, kSecPrivateKeyAttrs, privAttrs); CFErrorRef error = NULL; SecKeyRef privateKey = SecKeyCreateRandomKey(attrs, &error); if (privateKey) {     CFDataRef data = NULL;     OSStatus status = SecItemExport(privateKey, kSecFormatSSH, kSecItemPemArmour, NULL, &data);     if (status == errSecSuccess)     {         // ... save private key data đồ sộ a tệp tin ...     }     SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey);     if (publicKey)     {         status = SecItemExport(publicKey, kSecFormatSSH, kSecItemPemArmour, NULL, &data);         if (status == errSecSuccess)         {             // ... save public key data đồ sộ a tệp tin ...         }         CFRelease(publicKey);     }     CFRelease(privateKey); } CFRelease(privAttrs); CFRelease(attrs); 

This seems đồ sộ create valid RSA key pair, which I can add đồ sộ the Keychain on creation if I choose đồ sộ (setting permanent attribute đồ sộ true), but the exporting operation doesn’t over up with files I expect. The PEM armour seems not đồ sộ be correct, the text representation of the key begins and ends with -----BEGIN/END RSA PRIVATE KEY----- as opposed đồ sộ -----BEGIN/END OPENSSH PRIVATE KEY----- and the key structure looks different in general. If I try đồ sộ show key fingerprint using

ssh-keygen -l -f

I get response that “ is not a key tệp tin. If I, for example, try đồ sộ upload the public key đồ sộ GitHub đồ sộ use for SSH connection, it’s rejected, because “key is invalid, you must supply a key in OpenSSH public key format."

I’d appreciate if anyone points out what I’m doing wrong and whether this is achievable with Security framework at all.

Thanks,

-- Dragan

If you export an RSA key using

.formatSSH

, without the PEM wrapper, you’ll get data that looks lượt thích this:

% xxd formatSSH.dat | head -n 4
00000000: 5353 4820 5052 4956 4154 4520 4b45 5920  SSH PRIVATE KEY 
00000010: 4649 4c45 2046 4f52 4d41 5420 312e 310a  FILE FORMAT 1.1.
00000020: 0000 0000 0000 0000 0800 0800 a26b c310  .............k..
00000030: 4135 a3a7 209d 63d3 8952 7f3e 1821 e815  A5.. .c..R.>.!..

In contrast, if you use

ssh-keygen

đồ sộ generate a key (without a passphrase) and then decode the Base64, you’ll get data lượt thích this:

% xxd keygen.dat | head -n 4
00000000: 6f70 656e 7373 682d 6b65 792d 7631 0000  openssh-key-v1..
00000010: 0000 046e 6f6e 6500 0000 046e 6f6e 6500  ...none....none.
00000020: 0000 0000 0000 0100 0002 1700 0000 0773  ...............s
00000030: 7368 2d72 7361 0000 0003 0100 0100 0002  sh-rsa..........

These are clearly different. I’m not an OpenSSH expert but my understanding is that the

SSH PRIVATE KEY FILE FORMAT 1.1

is a legacy format and

openssh-key-v1

is the more modern one. AFAIK macOS has no API đồ sộ generate the latter. You may be able đồ sộ convince OpenSSH đồ sộ accept the legacy format, or use it đồ sộ convert the legacy format đồ sộ the modern format. If not, you’ll have đồ sộ write your own code đồ sộ vì thế this conversion.

Share and Enjoy

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

let myEmail = "eskimo" + "1" + "@apple.com"

If you export an RSA key using

.formatSSH

, without the PEM wrapper, you’ll get data that looks lượt thích this:

% xxd formatSSH.dat | head -n 4
00000000: 5353 4820 5052 4956 4154 4520 4b45 5920  SSH PRIVATE KEY 
00000010: 4649 4c45 2046 4f52 4d41 5420 312e 310a  FILE FORMAT 1.1.
00000020: 0000 0000 0000 0000 0800 0800 a26b c310  .............k..
00000030: 4135 a3a7 209d 63d3 8952 7f3e 1821 e815  A5.. .c..R.>.!..

In contrast, if you use

ssh-keygen

đồ sộ generate a key (without a passphrase) and then decode the Base64, you’ll get data lượt thích this:

% xxd keygen.dat | head -n 4
00000000: 6f70 656e 7373 682d 6b65 792d 7631 0000  openssh-key-v1..
00000010: 0000 046e 6f6e 6500 0000 046e 6f6e 6500  ...none....none.
00000020: 0000 0000 0000 0100 0002 1700 0000 0773  ...............s
00000030: 7368 2d72 7361 0000 0003 0100 0100 0002  sh-rsa..........

These are clearly different. I’m not an OpenSSH expert but my understanding is that the

SSH PRIVATE KEY FILE FORMAT 1.1

is a legacy format and

openssh-key-v1

is the more modern one. AFAIK macOS has no API đồ sộ generate the latter. You may be able đồ sộ convince OpenSSH đồ sộ accept the legacy format, or use it đồ sộ convert the legacy format đồ sộ the modern format. If not, you’ll have đồ sộ write your own code đồ sộ vì thế this conversion.

Share and Enjoy

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

let myEmail = "eskimo" + "1" + "@apple.com"

I have đồ sộ comment that I'm not surprised at all that it's you, who provided answers and help :-) Yeah, I've noticed the keys are different, but I didn't know anything about the legacy format "1.1" (I mentioned I'm not very experienced with cryptography).

In any case, thanks for clarification.

Hey @milke I've come across the same problem while working on this Swift Package, did you ever solve it?

The SPM I'm working on https://github.com/App-Maker-Software/GitProviders

@joehinkle11, I did solve it, but not using system APIs. I use: https://www.openssh.com/portable.html

I actually created my own small library, aimed only đồ sộ create those keys and stripped away all other unnecessary code, trying đồ sộ keep its footprint as small as possible.

First post date Last post date

Q