2010-11-18 10 views
11

मैं TCP सॉकेट सर्वर है एन्क्रिप्ट करने के लिए और मैं डब्ल्यू/SSL का उपयोग ओ निम्न कार्य करना चाहते हैं:iphone के लिए RSA सार्वजनिक कुंजी भेज सकते हैं और इसका इस्तेमाल

  1. सर्वर पर, आरएसए कुंजी युग्म बनाने (मुझे पता है कि openssl की क्रिप्टो लाइब्रेरी का उपयोग करके ऐसा करने के लिए)
  2. सर्वर पर, आईफोन पर सार्वजनिक कुंजी भेजें और निजी कुंजी रखें।
  3. क्लाइंट (आईफोन) पर, SecKeyEncrypt का उपयोग करके सार्वजनिक कुंजी का उपयोग करके एक संदेश एन्क्रिप्ट करना चाहते हैं।
  4. सर्वर पर, संदेश डिक्रिप्ट करें।

संदेश इतना छोटा है कि पीकेसीएस 1 गद्देदार परिणाम 128 बाइट्स में फिट बैठता है।

मुझे नहीं पता कि 2 ~ 4 कैसे करें। कोई जानता है?

+0

नहीं एक सवाल के रूप में जहाँ तक मैं देख सकते हैं। –

+0

क्षमा करें ग्रेग। मैंने अभी एक सवाल जोड़ा है। –

+0

यह एसएसएल के बिना सुरक्षित नहीं होगा; यह एक [मध्य हमले में आदमी] के अधीन होगा (http://en.wikipedia.org/wiki/Man_in_the_middle_attack)। – cobbal

उत्तर

18

यह वही करना चाहिए जो आप पूछ रहे हैं - यह सर्वर की सार्वजनिक कुंजी के साथ डेटा को एन्क्रिप्ट करता है। यह एमआईटीएम हमलों के अधीन नहीं है, जब तक कि हमलावर की आपकी निजी कुंजी और उसका पासवर्ड की प्रतिलिपि न हो (गैर-एसएसएल के माध्यम से संचार करना, फिर भी है, लेकिन सर्वर की कानूनी सार्वजनिक कुंजी के साथ आपके द्वारा एन्क्रिप्ट किया गया डेटा डिक्रिप्ट करना लगभग असंभव होगा) ।

मैंने ऐप्पल के दस्तावेज़ों, इस साइट, ऐप्पल डेवलपर फ़ोरम और शायद कहीं और इसे एक साथ जोड़ दिया। तो हर किसी के लिए धन्यवाद मैंने कोड को पकड़ लिया! इस कोड को कई चीजें हो जाती है:

  1. आप पहले से ही अपने RSA कुंजी जोड़े बना लेने के बाद (मैं एक 4096 बिट कुंजी का उपयोग कर रहा हूँ और यह काफी तेजी से लगता है) और, निजी कुंजी का उपयोग कर, बनाया एक DER- एन्कोड सर्टिफिकेट जिसे "cert.cer" कहा जाता है जिसे आपने अपने ऐप के संसाधन संसाधन में रखा है (जाहिर है, आप अपने सर्वर से प्रमाण भी डाउनलोड कर सकते हैं, लेकिन फिर आप एमआईटीएम हमलों के लिए खुले हैं)। डिफ़ॉल्ट रूप से, ओपनएसएसएल एक पीईएम एन्कोडेड प्रमाण उत्पन्न करता है, इसलिए आपको इसे "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER" के रूप में परिवर्तित करना होगा। आईओएस पीईएम पर बारफ होगा। मैं प्रमाण का उपयोग करने का कारण यह है कि काम करना वास्तव में आसान है, और आईओएस में समर्थित है। केवल सार्वजनिक कुंजी का उपयोग नहीं करना है (हालांकि यह किया जा सकता है)।

  2. आपने अपनी परियोजना में सुरक्षा.फ्रेमवर्क जोड़ा है और आप #सुरक्षा/सुरक्षा.h > आयात करें।

/* एन्क्रिप्टेड पाठ, या नहीं के बराबर का एक NSData वापस लौटाता एन्क्रिप्शन असफल रहा था।
(उदाहरण के लिए dataWithContentsOfFile से :,) NSData के रूप में 509 प्रमाणपत्र ले जाता है */

+(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 – rob5408

+0

हैलो स्काबा, मेरे पास जावा सर्वर से public.key फ़ाइल है, अब मुझे आईओएस एसडीके में उस कुंजी का उपयोग करके अपना पासवर्ड एन्क्रिप्ट करना होगा ... मैं आईओएस में .key एक्सटेंशन फ़ाइल को पढ़ने में सक्षम नहीं हूं। – Apple

+0

तपन: आपको एक डीईआर एन्कोडेड कुंजी का उपयोग करना होगा। यह सुनिश्चित करने के लिए जांचें कि आपकी public.key डीईआर एन्कोडेड है, अन्यथा आपको इसका उपयोग करने के लिए इसे बदलने की आवश्यकता होगी। ऊपर मेरा # 1 देखें। – scaba

1

अच्छा, मुझे लगता है कि आपको अपनी सार्वजनिक कुंजी को बाहरी दुनिया (आपके मामले में आईफोन) में प्रकाशित करने की आवश्यकता होगी। अपनी सार्वजनिक कुंजी को व्यवस्थित करने वाले प्रमाण पत्र को प्रकाशित करने का सबसे अच्छा तरीका है, और आईफोन ऐप इसे डाउनलोड कर सकता है। फिर आईफोन एप्लिकेशन PGP के सिद्धांत का उपयोग सममित एल्गो (जैसे एईएस) के साथ डेटा एन्क्रिप्ट करने के लिए कर सकता है और सार्वजनिक कुंजी के साथ सममित को एन्क्रिप्ट कर सकता है। सर्वर में एप्लिकेशन संदेश प्राप्त करेगा, सममित कुंजी को अपनी निजी कुंजी के साथ डिक्रिप्ट करेगा, और उसके बाद एन्क्रिप्टेड डेटा को इस प्रकार प्राप्त सममित कुंजी के साथ डिक्रिप्ट करेगा।

लेकिन जैसा कि कोबबल ने कहा था, कोई भी सर्वर और आईफोन के बीच संदेश को रोक सकता है और इसे बदल सकता है, और सर्वर को यह नहीं पता होगा कि अगर उसने 'वास्तव में' iPHone से डेटा प्राप्त किया है, तब तक जब तक आप इसे साइन इन नहीं करते एक एसएसएल प्रमाणपत्र (यानी आईफोन की निजी कुंजी के साथ विधि का हैश एन्क्रिप्ट करें)।

मेरा सुझाव है, इसे स्वयं करने के बजाए availale तृतीय पक्ष एप्लिकेशन का उपयोग करें, क्योंकि वे कुछ कार्यान्वयन में विफल हो सकते हैं। पीजीपी एक सार्वजनिक उपलब्ध पुस्तकालय है, जिसका आप उपयोग कर सकते हैं।

संबंधित मुद्दे