2014-02-27 23 views
2

我試圖使用AES加密算法解密文檔。針對少數文檔格式的AES加密算法不能解密

我從enc文件中獲取密鑰並在算法中使用它。

當我試圖解密文件時,我無法解密文件的幾種格式,如docx, xlsx, pptx and txt文件。請在下面找到我的代碼。

- (NSData *)AES256Decrypt 
{ 

NSString* path = [[NSBundle mainBundle] pathForResource:<filename> ofType:@"enc"]; 

// fetch key data from the key file 
NSData *keyData = [NSData dataWithContentsOfFile:path]; 

NSUInteger dataLength = [self length]; 

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

size_t numBytesDecrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, 
             [keyData bytes], kCCKeySizeAES256, 
             NULL 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

if (cryptStatus == kCCSuccess) 
{ 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
} 

free(buffer); 
return nil; 
} 

我加了上面的方法作爲NSData的類別。

我試圖在客戶端進行加密和解密。即使該文檔也無法正確解密。當我嘗試打開解密文件時,使用QLPreviewController查看文檔時出現office open xml word processing document錯誤。

我無法找到爲什麼只發生少量文件的原因。任何人都可以幫助我解決這個問題。 感謝

回答

0

我看到這裏有一個問題:

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, 
            [keyData bytes], kCCKeySizeAES256, 
            NULL 
            [self bytes], dataLength, /* input */ 
            buffer, bufferSize, /* output */ 
            &numBytesDecrypted); 

在這段代碼[keyData bytes]應該是你的密碼。但是,你這樣做是:

NSData *keyData = [NSData dataWithContentsOfFile:path]; 

文檔的數據應該在您目前有[self bytes]的參數傳遞。

編輯: 看到你的評論後,我意識到該文件包含密鑰。

我使用AES在我的項目之一,我用這個代碼:

// '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: (char *)keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding]; 

在最後一行的「鑰匙」是我的密碼。而我所說的CCCrypt功能是這樣的:

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

keyData字節是密碼,[self bytes]是文檔。 [NSData dataWithContentsOfFile:path]是我獲取算法密鑰的enc文件(密鑰文件)的內容。 [self bytes]是加密文檔的內容。 – RAJA

+0

@RAJA好的,我現在明白了。見編輯答案 – Merlevede

+0

雅。我也在項目中使用了相同的內容。現在我需要使用enc文件中的密鑰。當我嘗試使用它不能單獨解密幾個​​文件。這是我的問題。 – RAJA

1

如果能夠解密指向一個可能的填充問題一些但不是所有的文件。我注意到你不提供kCCOptionPKCS7Padding。如果數據不是一個大小爲偶數的數據塊,則需要某種形式的填充。 (當然,可以使用類似CTR模式的流密碼,但這通常是一個糟糕的選擇。)

使用ECB模式(kCCOptionECBMode)非常糟糕,您應該真的使用默認的CBC以及iv。

參見Bob ‘n Alice On Security
Original
原始

ECB mode
ECB模式(伊芙愛ECB)

CBC mode
CBC模式

查看不同?還想使用ECB?

+0

在服務器端,該算法使用ECB模式來加密文檔。改變服務器算法也不在我手中。無論如何需要使用這種算法進行解密。謝謝。 – RAJA

+0

對,我明白了:安全性並不是那麼重要。我打賭塔吉特說同樣的事情,結果很好 - 哦等等。看,如果你是一個專業人士,你不會做這樣的事情:犧牲安全,因爲你不願意表態。如果你是專業人士,只告訴他們不要。簡單:不 - 我幾乎因爲不接受差的加密而被解僱 - 但我沒有。我從來沒有磕頭,我從來沒有被解僱。你和其他許多人必須學會爲這些事情站起來。每次我做完成它都做得很好,我贏得了尊重。你也可以。 – zaph

+0

如果我們想要像專業人員一樣對待,我們需要像專業人員一樣行事。 – zaph

1

跳出來的第一個問題是您已經指定了AES128算法,但也爲AES256算法設置了密鑰長度。據我所知,你需要使用與算法匹配的密鑰長度。

我會改變CCrypt調用如下,看看是否處理這個問題。

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionECBMode, 
             [keyData bytes], kCCKeySizeAES128, 
             NULL 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

另外,當然,如果你的目的是使用AES256,這樣做:

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES256, kCCOptionECBMode, 
             [keyData bytes], kCCKeySizeAES256, 
             NULL 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

在解密時,你並不真的需要墊輸出緩衝區的大小,但它肯定沒有按這樣做並不痛。其次,而不是使用malloc作爲輸出緩衝區,使用NSMutableData可能會更好。下面是一些代碼,我已經成功地用來做類似的事情:

NSMutableData * buffer = [NSMutableData dataWithLength:bufferSize]; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES256, kCCOptionECBMode, 
             [keyData bytes], kCCKeySizeAES256, 
             NULL 
             [self bytes], 
             dataLength, 
             buffer.mutableBytes, 
             buffer.length, 
             &numBytesDecrypted); 

if (cryptStatus == kCCSuccess) 
{ 
    [buffer setLength:numBytesDecrypted]; 
    return buffer; 
} 
return nil; 

最後,對於加密的東西一個很好的資源可以在羅布納皮爾的著作中找到。請參閱http://robnapier.net/aes-commoncrypto/開始。

+0

我沒有找到任何算法,如你所說(kCCAlgorithmAES256)。即使在Napier的樣本中,也使用kCCAlgorithmAES128。你可以請檢查一下,讓我知道。當我嘗試使用可變數據而不是使用malloc時,之前可用的解密也不能正常工作。 – RAJA

+0

嗨拉賈 - 你是正確的 - 我看看CommonCrypto.h,我看到,該軟件包目前只支持128位AES。我所做的一點是密鑰長度必須與塊長度匹配,並且我沒有檢查是否支持256位。 – jims

+0

關於NSMutableData,如果你有其他的情況下,你成功地使用緩衝區的malloc,我會說這是堅持這一點是安全的。不知道爲什麼NSMutableData不適合你。回到您的主要問題 - 您確定數據提供商正在使用256位算法進行加密嗎?你有沒有試過用128位算法解密?另外,是否有可能加密的數據可能是Base64編碼的,或者其他類型的編碼?編碼用於傳輸的加密數據是很常見的。 – jims