Шифрование строки AES в Objective-C - PullRequest
11 голосов
/ 03 сентября 2011

Моему приложению Objective-C требуется шифрование текста / строк (в частности, ).

Я знаю, что AES - самый безопасный метод шифрования, доступный для потребительского использования. Я также понимаю, как преобразовать строки в данные и обратно ... (просто новичок).

Многие веб-страницы и вопросы о шифровании с помощью AES неясны, и ни на одной из них не указано, как использовать данный код. Например, на веб-странице может быть сказано: «вот код ... вот что он делает ...», но нет объяснения, как его использовать.

Я нашел этот код в результате многочисленных исследований:

#import "<CommonCrypto/CommonCryptor.h>"
@implementation NSMutableData(AES)

Для шифрования:

- (NSMutableData*) EncryptAES:(NSString *)key {
    char keyPtr[kCCKeySizeAES256+1];
    bzero( keyPtr, sizeof(keyPtr) );

    [key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF16StringEncoding];
    size_t numBytesEncrypted = 0;

    NSUInteger dataLength = [self length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    NSMutableData *output = [[NSData alloc] init];

    CCCryptorStatus result = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL, [self mutableBytes], [self length], buffer, bufferSize, &numBytesEncrypted);

    output = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesEncrypted];

    if(result == kCCSuccess) {
        return output;
    }
        return NULL;
    }

Для расшифровки:

- (NSMutableData*)DecryptAES: (NSString*)key andForData:(NSMutableData*)objEncryptedData {

    char  keyPtr[kCCKeySizeAES256+1];
    bzero( keyPtr, sizeof(keyPtr) );

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF16StringEncoding];

    size_t numBytesEncrypted = 0;

    NSUInteger dataLength = [self length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer_decrypt = malloc(bufferSize);    
    NSMutableData *output_decrypt = [[NSData alloc] init];
    CCCryptorStatus result = CCCrypt(kCCDecrypt , kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL, [self mutableBytes], [self length], buffer_decrypt, bufferSize, &numBytesEncrypted);

    output_decrypt = [NSMutableData dataWithBytesNoCopy:buffer_decrypt length:numBytesEncrypted];

    if(result == kCCSuccess) {
        return output_decrypt;
    } 
        return NULL;
    }
}

Это код, который я сделал, и я хотел бы соответствовать приведенному выше коду:

- (void)Encrypt {
    //Convert NSString to NSData so that it can be used to encrypt the Input
    NSString *Input  = [Inputbox text];
    NSData *InputData = [Input dataUsingEncoding:NSUTF8StringEncoding];
    //What to do here
}

Как мне использовать этот код, эти методы? Куда это идет в моем файле реализации?

Ответы [ 3 ]

6 голосов
/ 04 сентября 2011

Поскольку до сих пор это игнорировалось:

CCCryptorStatus result = CCCrypt( kCCDecrypt , kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                 keyPtr, kCCKeySizeAES256,
                                 **NULL**,
                                 [self mutableBytes], [self length],
                                 buffer_decrypt, bufferSize,
                                 &numBytesEncrypted );

Из заголовочного файла CommonCrypto / CommonCryptor.h:

@ param iv Вектор инициализации, необязательно.Используется блочными шифрами, когда включен режим Cipher Block Chaining (CBC).Если он есть, он должен быть той же длины, что и размер блока выбранного алгоритма.Если выбран режим CBC (из-за отсутствия бита kCCOptionECBMode в флагах параметров) и не присутствует IV, то будет использоваться IV NULL (все нули).Этот параметр игнорируется, если используется режим ECB или выбран алгоритм потокового шифра.

NULL, выделенный жирным шрифтом, соответствует IV.К сожалению, тот, кто разработал API, сделал его необязательным.Это делает этот режим CBC по существу эквивалентным ECB, который не рекомендуется по ряду причин .

5 голосов
/ 03 сентября 2011

В этой строке вверху указано, что вы добавляете функциональность AES в NSMutableData:

@implementation NSMutableData(AES)

В Objective-C это называется категорией; категории позволяют расширить существующий класс.

Этот код обычно помещается в файл с именем NSMutableData-AES.m. Создайте файл заголовка, NSMutableData-AES.h. Он должен содержать:

@interface NSMutableData(AES)
- (NSMutableData*) EncryptAES: (NSString *) key;
@end

Включите (#import) этот заголовок в ваш основной файл. Добавьте в код код вызова функции шифрования:

NSData *InputData = [Input dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [InputData EncryptAES:@"myencryptionkey"];

Аналогично для расшифровки.

0 голосов
/ 17 мая 2019

Я добился успеха, используя AES с кодами ниже:

Заголовочный файл

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>

NS_ASSUME_NONNULL_BEGIN

@interface SecurityUtils : NSObject

+ (NSString *)encrypt:(NSString *)plainText error:(NSError **)error;
+ (NSString *)decrypt:(NSString *)plainText error:(NSError **)error;

@end

NS_ASSUME_NONNULL_END

Файл реализации

NSString *const IV = @"AEE0515D0B08A4E4";
NSString *const KEY =  @"9336565521E5F082BB5929E8E033BC69";


#import "SecurityUtils.h"


@implementation SecurityUtils


+ (NSString *)encrypt:(NSString *)plainText error:(NSError **)error {
    NSMutableData *result =  [SecurityUtils doAES:[plainText dataUsingEncoding:NSUTF8StringEncoding] context: kCCEncrypt error:error];
    return [result base64EncodedStringWithOptions:0];
}


+ (NSString *)decrypt:(NSString *)encryptedBase64String error:(NSError **)error {
    NSData *dataToDecrypt = [[NSData alloc] initWithBase64EncodedString:encryptedBase64String options:0];
    NSMutableData *result = [SecurityUtils doAES:dataToDecrypt context: kCCDecrypt error:error];
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];

}

+ (NSMutableData *)doAES:(NSData *)dataIn context:(CCOperation)kCCEncrypt_or_kCCDecrypt error:(NSError **)error {
        CCCryptorStatus ccStatus   = kCCSuccess;
        size_t          cryptBytes = 0;
        NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeBlowfish];
        NSData *key =[KEY dataUsingEncoding:NSUTF8StringEncoding];
        NSData *iv = [IV dataUsingEncoding:NSUTF8StringEncoding];

        ccStatus = CCCrypt( kCCEncrypt_or_kCCDecrypt,
                           kCCAlgorithmAES,
                           kCCOptionPKCS7Padding,
                           key.bytes,
                           key.length,
                           (iv)?nil:iv.bytes,
                           dataIn.bytes,
                           dataIn.length,
                           dataOut.mutableBytes,
                           dataOut.length,
                           &cryptBytes);

        if (ccStatus == kCCSuccess) {
            dataOut.length = cryptBytes;
        }
        else {
            if (error) {
                *error = [NSError errorWithDomain:@"kEncryptionError"
                                             code:ccStatus
                                         userInfo:nil];
            }
            dataOut = nil;
        }

        return dataOut;
}


@end

IOS TESTING

NSError *error;
NSString *encrypted = [SecurityUtils encrypt:@"My Secret Text" error:&error];
NSLog(@"encrypted: %@",encrypted);
NSLog(@"decrypted: %@",[SecurityUtils decrypt:encrypted error:&error]);

Наконец, результаты тестов:

IOS OUTPUT

2019-05-16 21:38:02.947043-0300 MyApp[63392:1590665] encrypted: EJ41am5W1k6fA7ygFjTSEw==
2019-05-16 21:38:02.947270-0300 MyApp[63392:1590665] decrypted: My Secret Text
...