Подтвердить что ты не робот

Отправить открытый ключ RSA на iphone и использовать его для шифрования

У меня есть сервер сокетов TCP, и я хочу сделать следующее без использования SSL:

  • На сервере сделайте пару ключей RSA (я знаю, как это сделать, используя криптографическую библиотеку openssl)
  • На сервере отправьте открытый ключ на iphone и сохраните закрытый ключ.
  • На клиенте (iphone) вы хотите зашифровать сообщение с помощью открытого ключа, используя SecKeyEncrypt.
  • На сервере расшифруйте сообщение.

Сообщение достаточно короткое, чтобы результат PKCS1 дополнялся 128 байтами.

Я не знаю, как сделать 2 ~ 4. Кто-нибудь знает?

4b9b3361

Ответ 1

Это должно делать то, что вы просите - оно шифрует данные с помощью открытого ключа сервера. Он не подвержен атакам MITM, если у злоумышленника нет копии вашего закрытого ключа и его пароля (однако, по-прежнему не выполняется SSL, но данные, которые вы шифруете с помощью открытого ключа сервера, почти невозможно расшифровать),

Я собрал это вместе с документами Apple, на этом сайте, на форумах разработчиков Apple и, возможно, в других местах. Так спасибо всем, что я скрепил код от! Этот код предполагает несколько вещей:

  • Вы уже создали пары ключей RSA (я использую 4096-битный ключ, и это кажется достаточно быстрым) и, используя закрытый ключ, создал DER-закодированный сертификат под названием cert.cer, который вы вложили в свой ресурс вашего приложения (очевидно, вы также можете загрузить сертификат со своего сервера, но затем снова открыты атаки MITM). По умолчанию OpenSSL генерирует сертификат, закодированный PEM, поэтому вы должны преобразовать его с помощью "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS будет зависеть от PEM. Причина, по которой я использую сертификат, на самом деле проще работать, и поддерживается в iOS. Использование только открытого ключа не является (хотя это можно сделать).

  • Вы добавили Security.framework в свой проект, и вы #import < Security/Security.h > .

/*    Возвращает NSData зашифрованного текста или nil, если шифрование не удалось.
   Принимает сертификат X.509 как NSData (например, из dataWithContentsOfFile:) */

+(NSData *)encryptString:(NSString *)plainText withX509Certificate:(NSData *)certificate {

    SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificate);
    SecPolicyRef policy = SecPolicyCreateBasicX509();
    SecTrustRef trust;
    OSStatus status = SecTrustCreateWithCertificates(cert, policy, &trust);

    SecTrustResultType trustResult;
    if (status == noErr) {
        status = SecTrustEvaluate(trust, &trustResult);
    }

    SecKeyRef publicKey = SecTrustCopyPublicKey(trust);

    const char *plain_text = [plainText UTF8String];
    size_t blockSize = SecKeyGetBlockSize(publicKey);
    NSMutableData *collectedCipherData = [NSMutableData data];

    BOOL success = YES;
    size_t cipherBufferSize = blockSize;
    uint8_t *cipherBuffer = malloc(blockSize);

    int i;
    for (i = 0; i < strlen(plain_text); i += blockSize-11) {
        int j;
        for (j = 0; j < blockSize-11 && plain_text[i+j] != '\0'; ++j) {
            cipherBuffer[j] = plain_text[i+j];
        }

        int result;
        if ((result = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, cipherBuffer, j, cipherBuffer, &cipherBufferSize)) == errSecSuccess) {
            [collectedCipherData appendBytes:cipherBuffer length:cipherBufferSize];
        } else {
            success = NO;
            break;
        }
    }

    /* Free the Security Framework Five! */
    CFRelease(cert);
    CFRelease(policy);
    CFRelease(trust);
    CFRelease(publicKey);
    free(cipherBuffer);

    if (!success) {
        return nil;
    }

    return [NSData dataWithData:collectedCipherData];
}

Ответ 2

Ну, я думаю, вам нужно будет публиковать свой открытый ключ для внешнего мира (iPhone в вашем случае). Сделать лучший способ - опубликовать сертификат, содержащий ваш открытый ключ, и приложение iPhone может его загрузить. Затем приложение iPhone может использовать принцип PGP для шифрования данных с помощью симметричного алгоритма (например, AES) и шифрования симметричного открытого ключа. Приложение на сервере получит сообщение, расшифрует симметричный ключ своим личным ключом и затем расшифрует зашифрованные данные с полученным таким образом симметричным ключом.

Но, как сказал коббал, любой может перехватить сообщение между сервером и iPhone и может его изменить, и сервер не узнает, действительно ли он "получил" данные от iPHone, если вы не подписываете его, используя SSL-сертификат (т.е. шифрование хэша метода с помощью закрытого ключа iPhone).

Мое предложение состоит в том, чтобы использовать дополнительное стороннее приложение вместо того, чтобы делать это самостоятельно, так как это может быть какое-то смещение в реализации tghe. PGP - общедоступная библиотека, которую вы можете использовать.