2012-05-08 42 views
1

最近我正在實現一個使用3DES的加密算法。但是,我發現4096數據塊的前8個字節總是被損壞。但可以肯定的是,它可以在java中正確解密。以下是我的代碼:CCCryptor 3DES解密的前8個字節總是被損壞?

+ (void) DecryptBy3DES:(NSInputStream*)strmSrc Output:(NSOutputStream*)strmDest CryptoRef:(CCCryptorRef)tdesCrypto 
{  
    size_t dataOutMoved; 
    uint8_t inputBuf[BlockSize]; 
    uint8_t outputBuf[BlockSize]; 

    CCCryptorStatus cryptStatus; 
    int iBytesRead = 0; 
    int iBuffUsed = 0; 

    while ((iBytesRead = [strmSrc read:inputBuf maxLength:BlockSize]) > 0) 
    { 
     cryptStatus = CCCryptorUpdate(tdesCrypto, &inputBuf, iBytesRead, &outputBuf, BlockSize, &dataOutMoved); 
     assert(cryptStatus==noErr); 
     [strmDest write:outputBuf maxLength:dataOutMoved]; 
    } 

    CCCryptorReset(tdesCrypto, nil); 
} 

其中的塊大小爲4096

我重用CCCryptoRef tdesCrypto解密幾個街區。第一個要解密的塊是正確的,但是下面的塊在開始時都有損壞的字節。我也嘗試重置CCCryptoRef,這似乎是徒勞的。

我真的很困惑。任何人都有同樣的問題?

+0

好吧,我找到原因... –

+1

不要讓我們猜測。是什麼原因?錯誤的IV? – SquareRootOfTwentyThree

+2

如果第一個塊是正確的,那麼它可能使用零IV。後續塊不正確可能會使用錯誤的模式。 Zero IV CBC,使用ECB解密會產生這些症狀。 – rossum

回答

0

忘記我以前的答案,我把它刪除了。你在緩衝區中得到「錯誤的字節」的原因是它們是你之前試圖解密的緩衝區的純文本的最後8個字節。

必須呼叫CCCryptorFinal()CCCryptorUpdate()最後一次通話之後。這將在寫入純文本的最後幾個字節之前刪除填充字節。由於密碼內部不知道最後一個緩衝區的最後一個塊是否包含填充字節,因此它尚不能將數據寫入輸出緩衝區。

請不要在while循環中銷燬或重置CCCryptor。只需簡單地將呼叫添加到CCCryptorFinal()之後,並且不要忘記將結果輸出寫入流。之後你可以重置CCCryptor。

我假設(猜)DESEde與CBC模式和PKCS#5填充在這裏。看到wikipedia,看看我在說什麼。

+0

抱歉這個問題持續了很長時間,沒有提供足夠的信息。我沒有使用填充並使用CBC模式,因此我必須在下一次操作前重置IV。無論如何,謝謝你的回答。 –

0

這裏是我的CryptoRef:

CCCryptorCreateWithMode(kCCEncrypt, kCCModeCBC, kCCAlgorithm3DES, ccNoPadding, [abIV bytes], [abKey bytes], [abKey length], nil, 0, 0, kCCModeOptionCTR_BE, &cryptRef); 

由於我使用CBC模式和ccNoPadding,沒有必要打電話給CCCryptorFinal()。相反,當我完成一個操作(即完成加密/解密一個文件等)時,我應該調用CCCryptorReset()在下一次操作之前將CryptoRef的iv重置爲初始狀態。或者第一塊數據將會有缺陷。

感謝您的評論,並遺憾地將此問題留在後面。我希望這可以幫助遇到同樣問題的人。