Điều này sẽ làm những gì bạn đang yêu cầu - nó mã hóa dữ liệu bằng khóa công khai của máy chủ. Nó không bị tấn công MITM, trừ khi kẻ tấn công có một bản sao khóa cá nhân và mật khẩu của nó (giao tiếp qua SSL không, tuy nhiên, vẫn còn, nhưng dữ liệu bạn mã hóa với khóa công khai hợp pháp của máy chủ sẽ gần như không thể giải mã được) .
Tôi đã kết hợp điều này với nhau từ tài liệu của Apple, trang web này, diễn đàn nhà phát triển Apple và có thể ở nơi khác. Vì vậy, cảm ơn tất cả mọi người tôi đã cribbed mã từ! Mã này giả định một số điều:
Bạn đã tạo cặp khóa RSA (Tôi đang sử dụng khóa 4096 bit và có vẻ đủ nhanh) chứng chỉ được gọi là "cert.cer" mà bạn đưa vào gói tài nguyên của ứng dụng (rõ ràng là bạn cũng có thể tải xuống chứng chỉ từ máy chủ của mình nhưng sau đó bạn lại mở các cuộc tấn công MITM). Theo mặc định, OpenSSL tạo ra một cert mã hóa PEM, vì vậy bạn phải chuyển đổi nó bằng "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS sẽ chặn trên PEM. Lý do tôi sử dụng một cert là nó thực sự dễ dàng hơn để làm việc với, và được hỗ trợ trong iOS. Chỉ sử dụng khóa công khai không phải là (mặc dù nó có thể được thực hiện).
Bạn đã thêm Security.framework vào dự án của mình và bạn #import <Security/Security.h>.
/* Trả về NSData của văn bản được mã hóa hoặc không mã hóa nếu không mã hóa.
Mất giấy chứng nhận X.509 như NSData (từ dataWithContentsOfFile :, ví dụ) */
+(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];
}
Không phải là một câu hỏi như xa như tôi có thể nhìn thấy. –
Xin lỗi Greg. Tôi vừa thêm một câu hỏi. –
Điều này sẽ không an toàn nếu không có SSL; nó sẽ phải chịu một [kẻ tấn công ở giữa] (http://en.wikipedia.org/wiki/Man_in_the_middle_attack). – cobbal