2010-11-18 42 views
11

Tôi có một máy chủ socket TCP và tôi muốn làm như sau w/o sử dụng SSL:gửi RSA khóa công khai vào iphone và sử dụng nó để mã hóa

  1. Trên máy chủ, hãy RSA cặp khóa (Tôi biết làm thế nào để thực hiện việc này bằng thư viện mã hóa của openssl)
  2. Trên máy chủ, gửi khóa công khai tới iphone và giữ khóa riêng.
  3. Trên máy khách (iphone), muốn mã hóa thư bằng khóa công khai, sử dụng SecKeyEncrypt.
  4. Trên máy chủ, giải mã thư.

Thư đủ ngắn để kết quả đệm PKCS1 vừa với 128 byte.

Tôi không biết cách thực hiện 2 ~ 4. Có ai biết?

+0

Không phải là một câu hỏi như xa như tôi có thể nhìn thấy. –

+0

Xin lỗi Greg. Tôi vừa thêm một câu hỏi. –

+0

Đ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

Trả lời

18

Đ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:

  1. 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).

  2. 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]; 
} 
+3

+1 cho "Khung bảo mật miễn phí Năm!" – rob5408

+0

hello scaba, tôi có tệp public.key từ máy chủ JAVA, bây giờ tôi cần mã hóa mật khẩu của mình bằng khóa đó trong ios sdk ... tôi không thể đọc tệp mở rộng .key trong ios. – Apple

+0

Tapan: Bạn phải sử dụng khóa mã hóa DER. Kiểm tra để đảm bảo rằng khóa công khai của bạn được mã hóa DER, nếu không bạn sẽ cần phải chuyển đổi nó để sử dụng nó. Xem số 1 của tôi ở trên. – scaba

1

Vâng, tôi đoán bạn sẽ cần phải xuất bản khóa công khai của bạn với thế giới bên ngoài (iPhone trong trường hợp của bạn). Cách tốt nhất là xuất bản chứng chỉ kết hợp khóa công khai của bạn và ứng dụng iPhone có thể tải xuống. Sau đó, ứng dụng iPhone có thể sử dụng nguyên tắc PGP để mã hóa dữ liệu với một bản đối xứng (như AES) và mã hóa đối xứng với khóa công khai. Ứng dụng trong máy chủ sẽ nhận được thông báo, giải mã khóa đối xứng bằng khóa riêng của nó và sau đó giải mã dữ liệu được mã hóa bằng khóa đối xứng do đó thu được. Tuy nhiên, như cobbal đã nói, bất kỳ ai cũng có thể chặn thông báo ở giữa máy chủ và iPhone và có thể thay đổi nó, và máy chủ sẽ không biết liệu nó có 'thực sự' nhận dữ liệu từ iPHone hay không, trừ khi bạn ký nó bằng cách sử dụng chứng chỉ SSL (tức là mã hóa hàm băm của phương thức bằng khóa riêng của iPhone).

Đề xuất của tôi là, sử dụng ứng dụng bên thứ ba của availale thay vì tự làm nó, vì chúng có thể là một số trong việc thực hiện tghe. PGP là một thư viện công khai, bạn có thể sử dụng.

Các vấn đề liên quan