Это должно делать то, что вы спрашиваете - оно шифрует данные с помощью открытого ключа сервера.Он не подвергается атакам 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.
/ * Возвращает 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];
}