2015-05-01 8 views
4

Я пытаюсь использовать шифрование DES для шифрования паролей (не спрашивайте, почему DES, я знаю, что он менее безопасен). Я делаю это в первый раз в iOS, поэтому мне пришлось положиться на другой пост о том, как это сделать.EXC_BAD_ACCESS Код 2 на CCCrypt

Когда я запускаю шифрование, он возвращает null, то же самое с расшифровкой уже зашифрованной строки (я использовал онлайн-инструмент для шифрования). Когда я ставлю точку останова, чтобы посмотреть, что происходит, она остановилась на CCCrypt, указав EXC_BAD_ACCESS (Code 2).

Я пробовал использовать разные CCOptions, но он всегда возвращает то же самое. Любые подсказки, что происходит не так? Требуется ли iv строка?

Я использовал следующую категорию NSString для шифрования и дешифрования строк -

#import "NSString+DES.h" 

@implementation NSString(DES) 

- (NSString*) encryptDES: (NSString *) key 
{ 
    const void *vplainText; 
    size_t plainTextBufferSize; 

    plainTextBufferSize = [self length]; 
    vplainText = (const void *) [self UTF8String]; 

    CCCryptorStatus ccStatus; 
    uint8_t *bufferPtr = NULL; 
    size_t bufferPtrSize = 0; 
    size_t *movedBytes; 

    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1); 
    bufferPtr = malloc(bufferPtrSize * sizeof(uint8_t)); 
    memset((void *)bufferPtr, 0x0, bufferPtrSize); 
    // memset((void *) iv, 0x0, (size_t) sizeof(iv)); 


    //NSString *initVec = @"init Vec"; 
    const void *vkey = (const void *) [key UTF8String]; 
    //const void *vinitVec = (const void *) [initVec UTF8String]; 

    ccStatus = CCCrypt(kCCEncrypt, 
         kCCAlgorithmDES, 
         kCCOptionPKCS7Padding | kCCOptionECBMode, 
         vkey, 
         kCCKeySizeDES, 
         NULL, 
         vplainText, 
         plainTextBufferSize, 
         (void *)bufferPtr, 
         bufferPtrSize, 
         movedBytes); 

    NSString *result; 
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes]; 
    result = [myData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 
    return result; 
} 

- (NSString *) decryptDES: (NSString *) key 
{ 
    const void *vplainText; 
    size_t plainTextBufferSize; 

    plainTextBufferSize = [self length]; 
    vplainText = (const void *) [self UTF8String]; 

    CCCryptorStatus ccStatus; 
    uint8_t *bufferPtr = NULL; 
    size_t bufferPtrSize = 0; 
    size_t *movedBytes; 

    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1); 
    bufferPtr = malloc(bufferPtrSize * sizeof(uint8_t)); 
    memset((void *)bufferPtr, 0x0, bufferPtrSize); 
    // memset((void *) iv, 0x0, (size_t) sizeof(iv)); 


    //NSString *initVec = @"init Vec"; 
    const void *vkey = (const void *) [key UTF8String]; 
    //const void *vinitVec = (const void *) [initVec UTF8String]; 

    ccStatus = CCCrypt(kCCDecrypt, 
         kCCAlgorithmDES, 
         kCCOptionPKCS7Padding | kCCOptionECBMode, 
         vkey, //"123456789", //key 
         kCCKeySizeDES, 
         NULL,// vinitVec, //"init Vec", //iv, 
         vplainText, //"Your Name", //plainText, 
         plainTextBufferSize, 
         (void *)bufferPtr, 
         bufferPtrSize, 
         movedBytes); 

    NSString *result; 
    NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes]; 
    result = [myData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 
    return result; 
} 

@end 

Update:

Я проверил несколько мест и изменил код немного, шифрование работает, но не получает расшифровку с правильным значением.

Например, когда я использую YourName как строку и 12345 как ключ, я получаю Fu2sK61e7l5rkXRhAKjPWA== как зашифрованный код, но расшифровка возвращает +54qWCYTB5LkdARDZjAow== и не YourName.

Обновленный код:

#import "NSString+DES.h" 

@implementation NSString(DES) 

- (NSString*) encryptDES: (NSString *) key 
{ 
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *stringData = [self dataUsingEncoding:NSUTF8StringEncoding]; 
    size_t numBytesEncrypted = 0; 
    size_t bufferSize = stringData.length + kCCBlockSizeDES; 
    void *buffer = malloc(bufferSize); 

    CCCryptorStatus result = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, 
            keyData.bytes, kCCKeySizeDES, 
            NULL, 
            stringData.bytes, stringData.length, 
            buffer, bufferSize, 
            &numBytesEncrypted); 
    NSData *output = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 
    free(buffer); 
    if(result == kCCSuccess) 
    { 
     NSString *resultStr = [output base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 
     return resultStr; 
    } else { 
     NSLog(@"Failed DES encrypt..."); 
     return nil; 
    } 

} 

- (NSString *) decryptDES: (NSString *) key 
{ 
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *stringData = [[NSData alloc] initWithBase64EncodedString:self options:0]; 

    size_t numBytesEncrypted = 0; 
    size_t bufferSize = stringData.length + kCCBlockSizeDES; 
    void *buffer = malloc(bufferSize); 

    CCCryptorStatus result = CCCrypt(kCCDecrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, 
            keyData.bytes, kCCKeySizeDES, 
            NULL, 
            stringData.bytes, stringData.length, 
            buffer, bufferSize, 
            &numBytesEncrypted); 
    NSData *output = [NSData dataWithBytes:buffer length:numBytesEncrypted]; 
    free(buffer); 
    if(result == kCCSuccess) 
    { 
     NSString *resultStr = [output base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength]; 
     return resultStr; 
    } else { 
     NSLog(@"Failed DES decrypt..."); 
     return nil; 
    } 
} 

@end 
+0

@Bhavin 'ccStatus = CCCrypt (...);' является виновником здесь. – noob

+0

ok..had вы проверяете эту ссылку ... http: //stackoverflow.com/questions/11717193/exc-bad-access-code-2 –

+1

Режим ECB не использует iv. – zaph

ответ

1

Там, кажется, общая путаница в алгоритме, DES или 3DES, смесь используется, но ключ 3DES (24-байт). Ключ должен быть изменен на 8 байтов. Константа размера блока также должна быть изменена на kCCBlockSizeDES, но это не вызывает ошибки, так как это то же значение.

Для метода:

- (NSString *) decryptDES: (NSString *) key 

вызвана плохая ошибка доступа, поскольку никакого хранения не выделяются для movedBytes, только указатель. Измените объявление на:

size_t movedBytes; 

изменить ссылку на movedBytes в CCCrypt к &movedBytes.

Результат теста для шифрования:

строки: "Ваше имя"
ключ: "12345678"

movedBytes: 16
MyData: 136142f6 6cd98e01 af1eef46 28d36499
результат: E2FC9mzZjgGvHu9GKNNkmQ ==

Примечания от комментариев по запросу:

Режим ECB не использует iv.

Ключ должен быть точно 8-байтным для DES, если он короткий, результат будет неопределенным.В обновленном коде ключ равен 5 байтам, но длина указывается как 8-байтовые (kCCKeySizeDES), поэтому три пропущенных байта ключа будут любыми байтами, следующими за keyData.

В обновленном ответе не указан режим ECB, по умолчанию используется режим CBC. Добавить kCCOptionECBMode.

В Расшифровать не использовать Base64 кодирование, преобразование данных в NSString:

NSString * resultStr = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding]; 

При использовании онлайн-шифрования, который использует PHP Mcrypt функционировать последний блок данных будет неправильным, потому что Mcrypt не поддержка PKCS # 7, используется нестандартное и небезопасное заполнение нулей.

+0

Спасибо за ответ. Однако мне нужен алгоритм DES только потому, что уже есть некоторые зашифрованные данные, которые мне тоже нужно расшифровать. Кроме того, я проверил результат онлайн-инструментов и, похоже, не совпадал. Я использую этот инструмент - http://codebeautify.org/encrypt-decrypt – noob

 Смежные вопросы

  • Нет связанных вопросов^_^