отправьте открытый ключ RSA на iphone и используйте его для шифрования - PullRequest
11 голосов
/ 18 ноября 2010

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

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

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

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

Ответы [ 2 ]

18 голосов
/ 08 апреля 2011

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

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

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

  2. Вы добавили Security.framework в свой проект, и вы #import.

/ * Возвращает NSData зашифрованного текста или ноль, если шифрование не удалось.
Принимает сертификат 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];
}
1 голос
/ 19 ноября 2010

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

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

...