سؤال

هل يستطيع أحد أن لي نقطة في الاتجاه الصحيح من أجل أن تكون قادرة على تشفير سلسلة عودته سلسلة أخرى مع تشفير البيانات ؟ (كنت أحاول مع تشفير AES256.) أريد أن أكتب الأسلوب الذي يأخذ اثنين NSString الحالات ، رسالة لتشفير والآخر الرمز السري لتشفير مع - وأظن أني قد لتوليد مفتاح التشفير مع رمز المرور ، في الطريقة التي يمكن عكسها إذا كان المرور المرفقة مع البيانات المشفرة.طريقة ثم يجب إعادة NSString التي تم إنشاؤها من البيانات المشفرة.

لقد حاولت تقنية مفصلة في أول تعليق على هذا المنصب, ولكن لم الحظ حتى الآن.أبل CryptoExercise بالتأكيد لديه شيء, لكن لا يمكنني أن هذا منطقي...لقد رأيت الكثير من الإشارات إلى CCCrypt, لكنه فشل في كل حالة كنت استخدمه.

وأود أيضا أن تكون قادرة على فك تشفير مشفر السلسلة, ولكن آمل أن البساطة kCCEncrypt/kCCDecrypt.

هل كانت مفيدة؟

المحلول

حيث لم تنشر أي رمز من الصعب أن تعرف بالضبط ما هي المشاكل التي كنت تواجه.ومع ذلك ، فإن بلوق وظيفة لك رابط لا يبدو أن تعمل بشكل لائق...وبصرف النظر عن إضافي فاصلة في كل مكالمة CCCrypt() مما تسبب في أخطاء الترجمة.

لاحق التعليق على هذا المنصب يشمل هذا مقتبس رمز, الذي يعمل بالنسبة لي, و يبدو قليلا أكثر وضوحا.إذا قمت بتضمين التعليمات البرمجية الخاصة بهم من أجل NSData الفئة ، يمكنك كتابة شيء من هذا القبيل:(ملاحظة:على printf() المكالمات فقط من أجل إظهار حالة البيانات في نقاط مختلفة في تطبيق حقيقي, لا يعقل أن طباعة هذه القيم.)

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *key = @"my password";
    NSString *secret = @"text to encrypt";

    NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
    NSData *cipher = [plain AES256EncryptWithKey:key];
    printf("%s\n", [[cipher description] UTF8String]);

    plain = [cipher AES256DecryptWithKey:key];
    printf("%s\n", [[plain description] UTF8String]);
    printf("%s\n", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] UTF8String]);

    [pool drain];
    return 0;
}

وبالنظر إلى هذا الرمز ، وحقيقة أن البيانات المشفرة لا تترجم دائما بشكل جيد في NSString ، قد يكون أكثر ملاءمة لإرسال اثنين من الأساليب التي التفاف وظيفة تحتاج في إلى الأمام وعكس...

- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
    return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
}

- (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key {
    return [[[NSString alloc] initWithData:[ciphertext AES256DecryptWithKey:key]
                                  encoding:NSUTF8StringEncoding] autorelease];
}

هذا بالتأكيد يعمل على سنو ليوبارد ، @بوز التقارير التي CommonCrypto هو جزء من نظام التشغيل الأساسية على اي فون.كل 10.4 و 10.5 لديك /usr/include/CommonCrypto, على الرغم 10.5 رجل الصفحة CCCryptor.3cc و 10.4 لا حتى YMMV.


تحرير: انظر المتابعة هذا السؤال على استخدام ترميز Base64 لتمثيل البيانات المشفرة بايت كسلسلة (إذا رغبت في ذلك) باستخدام آمنة ، ضياع التحويلات.

نصائح أخرى

ولقد وضعت مجموعة من فئات لNSData وNSString الذي يستخدم الحلول الموجودة على <لأ href = "http://iphonedevelopment.blogspot.com/2009/02/strong-encryption-for-cocoa-cocoa-touch . هتمل # تعليقات "يختلط =" نوفولو noreferrer "> جيف امارش في بلوق و <لأ href =" https://stackoverflow.com/questions/1417893/encrypted-nsdata-to-nsstring-in-obj-c "> بعض التلميحات التي كتبها كوين تايلور هنا على تجاوز المكدس.

ويستخدم فئات تمديد NSData لتوفير التشفير AES256، ويقدم أيضا امتدادا لNSString إلى base64 في ترميز البيانات المشفرة بأمان إلى سلاسل.

وهنا مثال لإظهار الاستخدام لتشفير سلاسل:

NSString *plainString = @"This string will be encrypted";
NSString *key = @"YourEncryptionKey"; // should be provided by a user

NSLog( @"Original String: %@", plainString );

NSString *encryptedString = [plainString AES256EncryptWithKey:key];
NSLog( @"Encrypted String: %@", encryptedString );

NSLog( @"Decrypted String: %@", [encryptedString AES256DecryptWithKey:key] );

والحصول على كامل شفرة المصدر هنا:

<اقتباس فقرة>   

https://gist.github.com/838614

وشكرا لجميع النصائح المفيدة!

و- مايكل

@owlstead, بخصوص طلبك ل "آمن مشفر البديل من واحدة من الاجابات," يرجى الاطلاع RNCryptor.كانت مصممة على أن تفعل بالضبط ما كنت الطالبة (بنيت في استجابة مشاكل مع رمز المذكورة هنا).

RNCryptor يستخدم PBKDF2 مع الملح ، يوفر عشوائي الرابع ، وتعلق HMAC (ولدت أيضا من PBKDF2 مع الملح.دعم متزامن و غير متزامن العملية.

انتظرت قليلا على @QuinnTaylor تحديث جوابه ، ولكن بما أنه لم يكن هنا الجواب قليلا أكثر وضوحا في الطريقة التي سوف الحمل على XCode7 (وربما أكثر).أنا استخدم هذا في الكاكاو التطبيق ، لكنه على الأرجح سوف ينجح مع تطبيق دائرة الرقابة الداخلية أيضا.لا قوس الأخطاء.

لصق قبل أي @تنفيذ القسم في AppDelegate.م أو AppDelegate.مم الملف.

#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES256)

- (NSData *)AES256EncryptWithKey:(NSString *)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                     keyPtr, kCCKeySizeAES256,
                                     NULL /* initialization vector (optional) */,
                                     [self bytes], dataLength, /* input */
                                     buffer, bufferSize, /* output */
                                     &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

- (NSData *)AES256DecryptWithKey:(NSString *)key {
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    // fetch key data
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [self length];

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block.
    //That's why we need to add the size of one block here
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                     keyPtr, kCCKeySizeAES256,
                                     NULL /* initialization vector (optional) */,
                                     [self bytes], dataLength, /* input */
                                     buffer, bufferSize, /* output */
                                     &numBytesDecrypted);

    if (cryptStatus == kCCSuccess) {
        //the returned NSData takes ownership of the buffer and will free it on deallocation
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }

    free(buffer); //free the buffer;
    return nil;
}

@end

لصق هاتين الوظيفتين في @تنفيذ الدرجة التي تريدها.في حالتي اخترت @تنفيذ AppDelegate في AppDelegate.مم أو AppDelegate.م الملف.

- (NSString *) encryptString:(NSString*)plaintext withKey:(NSString*)key {
    NSData *data = [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
    return [data base64EncodedStringWithOptions:kNilOptions];
}

- (NSString *) decryptString:(NSString *)ciphertext withKey:(NSString*)key {
    NSData *data = [[NSData alloc] initWithBase64EncodedString:ciphertext options:kNilOptions];
    return [[NSString alloc] initWithData:[data AES256DecryptWithKey:key] encoding:NSUTF8StringEncoding];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top