Использование инфраструктуры безопасности MacOS для создания пар ключей, совместимых с OpenS SH - PullRequest
0 голосов
/ 10 апреля 2020

Мой самый первый вопрос здесь :-) Во-вторых, я не очень разбираюсь в криптографии и смежных темах, поэтому возможно, я пропускаю что-то совершенно очевидное.

Простой вопрос: Можно ли создать пары ключей, совместимые с OpenS SH, как это делает утилита s sh -keygen, используя платформу macOS Security? Допустим, я хочу сделать эквивалент следующей команды терминала:

ssh-keygen -t rsa -b 4096 -C “me@mail.com"

Я пытаюсь сделать это с помощью этого упрощенного фрагмента кода:

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);

Кажется, это создает действительную пару ключей RSA, которую я могу добавить в цепочку ключей при создании, если я решу (установив для постоянного атрибута значение true), но операция экспорта не заканчивается файлами, которые я ожидаю. Броня PEM, кажется, не является правильной, текстовое представление ключа начинается и заканчивается -----BEGIN/END RSA PRIVATE KEY----- в отличие от -----BEGIN/END OPENSSH PRIVATE KEY-----, и структура ключа в целом выглядит иначе. Если я пытаюсь показать отпечаток ключа, используя

ssh-keygen -l -f <keyfile>

, я получаю ответ, что «это не файл ключа». Если я, например, пытаюсь загрузить ключ publi c в GitHub для использования для подключения S SH он отклонен, поскольку «ключ недействителен, вы должны предоставить ключ в формате ключа OpenS SH publi c.»

Буду признателен, если кто-нибудь указывает на то, что я делаю неправильно, и достижимо ли это вообще с помощью Security Framework.

...