Я пытаюсь экспортировать открытые ключи EC с Android на iOS, как лучше всего это сделать?

Я пытаюсь выполнить обмен ключами 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, пожалуйста, помогите

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
406
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Можете ли вы объяснить, что означают headerBytes, или указать мне на некоторые ресурсы по этой теме?

AdmiralAnk 29.04.2020 15:44

@AdmiralAnk SecKeyCreateWithData ожидает необработанные биты открытого ключа. Другие системы вместо этого ожидают, что эти необработанные биты будут упакованы в структуру, называемую SubjectPublicKeyInfo, определенную в RFC 3280. Именно эта структура содержит заголовок с идентификатором объекта (OID), поэтому синтаксический анализатор может понять, какие данные находятся впереди. Это на стандартном языке под названием ASN.1, но iOS SDK не включает синтаксический анализатор ASN.1. Так что этот ответ взламывает биты напрямую.

NSDestr0yer 29.04.2020 21:51

Прямой взлом битов означает, что если вы используете другой размер ключа, то «фиксированный заголовок» будет другим. Примеры для 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, я написал об этом здесь

NSDestr0yer 29.04.2020 21:56

Другие вопросы по теме