Hello,I’m not very experienced in cryptography and related topics, so it may be possible I’m overlooking something quite obvious. The straightforward question is: is it possible to create OpenSSH compatible key pairs, like ssh-keyget utility does, using Security framework? Let’s say, I want to do the equivalent of the following terminal command:ssh-keygen -t rsa -b 4096 -C “me@mail.com"
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("me@mail.com")); 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 to a file ... } SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey); if (publicKey) { status = SecItemExport(publicKey, kSecFormatSSH, kSecItemPemArmour, NULL, &data); if (status == errSecSuccess) { // ... save public key data to a file ... } CFRelease(publicKey); } CFRelease(privateKey); } CFRelease(privAttrs); CFRelease(attrs); This seems to create valid RSA key pair, which I can add to the Keychain on creation if I choose to (setting permanent attribute to true), but the exporting operation doesn’t end up with files I expect. The PEM armour seems not to be correct, the text representation of the key begins and ends with -----BEGIN/END RSA PRIVATE KEY----- as opposed to -----BEGIN/END OPENSSH PRIVATE KEY----- and the key structure looks different in general. If I try to show key fingerprint usingssh-keygen -l -f <keyfile>I get response that “<keyfile> is not a key file. If I, for example, try to upload the public key to GitHub to 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
4
0
3.6k