2015-05-01 41 views
4

我試圖使用DES加密來加密密碼(不要問爲什麼DES,我知道它不太安全)。我在iOS中第一次這樣做,因此不得不依賴另一篇關於如何去做的文章。EXC_BAD_ACCESS CCCrypt上的代碼2

當我運行加密時,它返回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 

更新:

我已經檢查了幾個地方,並改變了代碼一點點,加密工作,但沒有使用正確的值解密。

例如,當我使用YourName string和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 ..你檢查這個鏈接... 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; 

更改參考movedBytesCCCrypt&movedBytes

測試輸出加密:

字符串: 「你的名字」
鍵: 「12345678」

movedBytes:16
myData的:136142f6 6cd98e01 af1eef46 28d36499
結果:E2FC9mzZjgGvHu9GKNNkmQ ==

備註請求評論:

ECB模式不使用iv。

DES的密鑰需要準確的8字節,如果是短的結果將是未定義的。在更新後的代碼中,密鑰爲5個字節,但長度爲8個字節(kCCKeySizeDES),所以三個丟失的密鑰字節將是keyData後面的任何字節。

更新的答案沒有指定ECB模式,默認是CBC模式。添加kCCOptionECBMode

在解密不使用Base64編碼,將數據轉換爲NSString:如果使用的是使用mcrypt的工作,因爲mcrypt的沒有數據的最後一個塊將是不正確的PHP在線加密

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

支持PKCS#7填充,它使用非標準和不安全的空填充。

+0

感謝您的回答。但是我只需要DES算法,因爲已經有一些我需要解密的加密數據了。除此之外,我檢查了在線工具的結果,它似乎不匹配。我正在使用這個工具 - http://codebeautify.org/encrypt-decrypt – noob

相關問題