Я пытаюсь выполнить обмен ключами EC между клиентами iOS и Android моего приложения. Я успешно перенес и сгенерировал их с iOS на Android. Но я не могу использовать ключи, сгенерированные в приложении Android, в iOS.
Я использую метод SecKeyCreateWithData в swift для генерации ключей из типа «Данные», но получаю эту ошибку:
Error Domain=NSOSStatusErrorDomain Code=-50 "EC public key creation from data failed"
Я использовал следующую кодировку в клиенте Android, она создает строку base64, которую я обрабатываю и передаю как данные SecKeyCreateWithData в swift
byte [] encodedPublicKey = PubKey.getEncoded();
String b64PublicKey = Base64.encodeToString(encodedPublicKey,Base64.DEFAULT);
Я хочу сгенерировать открытый ключ SecKeyRef, пожалуйста, помогите




API-интерфейсы Apple не полностью соответствуют стандартам, чтобы хорошо работать с другими платформами. Экспорт открытого ключа EC на iOS не включает фиксированный идентификатор заголовка. Поэтому функции импорта также ожидают, что заголовок отсутствует. Это означает, что вы должны удалить заголовок, который Android создает при импорте ключа Android EC.
Вот портативный пример:
CFMutableDataRef mutableData = CFDataCreateMutable(kCFAllocatorDefault, 0);
if (mutableData)
{
//Fixed schema header
const UInt8 headerBytes[] = { 0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,
0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,
0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,
0x42,0x00 };
const CFIndex headerSize = sizeof(headerBytes);
//Uncomment for exporting (such as via SecKeyCopyExternalRepresentation)
//CFDataAppendBytes(mutableData, headerBytes, headerSize);
//CFDataAppendBytes(mutableData, CFDataGetBytePtr(iosKeyData), CFDataGetLength(iosKeyData));
//For importing Android key data
CFDataAppendBytes(mutableData, CFDataGetBytePtr(androidKeyData), CFDataGetLength(androidKeyData));
CFDataDeleteBytes(mutableData, CFRangeMake(0, headerSize));
//Use the mutableData here (SecKeyCreateWithData)
CFRelease(mutableData);
}
Быстрая версия:
let mutableData = CFDataCreateMutable(kCFAllocatorDefault, CFIndex(0))
if mutableData != nil
{
//Fixed schema header
//var headerBytes = [0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00] as [UInt8]
let headerSize = 26
//Uncomment for exporting (such as via SecKeyCopyExternalRepresentation)
//CFDataAppendBytes(mutableData, &headerBytes, headerSize)
//CFDataAppendBytes(mutableData, CFDataGetBytePtr(iosKeyData), CFDataGetLength(iosKeyData))
//For importing Android key data
CFDataAppendBytes(mutableData, CFDataGetBytePtr(androidKeyData), CFDataGetLength(androidKeyData))
CFDataDeleteBytes(mutableData, CFRangeMake(CFIndex(0), headerSize))
//Use the mutableData here (SecKeyCreateWithData)
}
@AdmiralAnk SecKeyCreateWithData ожидает необработанные биты открытого ключа. Другие системы вместо этого ожидают, что эти необработанные биты будут упакованы в структуру, называемую SubjectPublicKeyInfo, определенную в RFC 3280. Именно эта структура содержит заголовок с идентификатором объекта (OID), поэтому синтаксический анализатор может понять, какие данные находятся впереди. Это на стандартном языке под названием ASN.1, но iOS SDK не включает синтаксический анализатор ASN.1. Так что этот ответ взламывает биты напрямую.
Прямой взлом битов означает, что если вы используете другой размер ключа, то «фиксированный заголовок» будет другим. Примеры для 384 или 521: var header384r1: [UInt8] = [0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22, 0x03, 0x62, 0x00]var header521r1: [UInt8] = [0x30, 0x81, 0x9B, 0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23, 0x03, 0x81, 0x86, 0x00] Если вас интересует ASN.1, я написал об этом здесь
Можете ли вы объяснить, что означают headerBytes, или указать мне на некоторые ресурсы по этой теме?