CCCryptor 3DES解密的前8个字节总是被破坏?

时间:2012-05-08 02:44:39

标签: objective-c ios cryptography

最近我正在实现一个使用3DES的加密算法。但是,我发现4096数据块的前8个字节总是被损坏。但它肯定可以在java中正确解密。以下是我的代码:

+ (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);
}

其中BlockSize为4096。

我重复使用CCCryptoRef tdesCrypto来解密几个块。要解密的第一个块是正确的,但是下面的块在开始时都有损坏的字节。我也尝试重置CCCryptoRef,这似乎是徒劳的。

我真的很困惑。任何人都有同样的问题吗?

2 个答案:

答案 0 :(得分:0)

忘记我之前的回答,我删除了它。您在缓冲区中获得“错误字节”的原因是它们是您之前尝试解密的缓冲区的纯文本的最后8个字节。

必须 在最后一次致电CCCryptorFinal()后立即致电CCCryptorUpdate()。这将在写入纯文本的最后几个字节之前删除填充字节。因为密码在内部不知道最后一个缓冲区的最后一个块包含填充字节,所以它不能将数据写入输出缓冲区。

请勿在while循环中销毁或重置CCCryptor。只需在之后添加对CCCryptorFinal()的调用,并且不要忘记将结果输出也写入流。之后你可以重置CCCryptor。

我假设(猜测)在这里使用CBC模式和PKCS#5填充进行DESede。请参阅wikipedia,了解我在说什么。

答案 1 :(得分: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重置为初始状态。或者第一个数据块将是缺陷。

感谢您的评论并抱歉留下了这个问题。我希望这可以帮助那些遇到同样问题的人。