CCCryptor 3DES 解密的前 8 个字节总是损坏



最近我正在实现一种使用 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);
}

其中块大小为 4096。

我重用了CCCryptoRef tdesCrypto来解密几个区块。要解密的第一个块是正确的,但随后的块在开始时都有损坏的字节。我还尝试重置CCCryptoRef,这似乎是徒劳的。

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

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

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

请不要在while循环中破坏或重置CCCryptor。只需将调用添加到CCCryptorFinal()之后,并且不要忘记将生成的输出也写入流。之后,您可以重置CCCryptor。

我假设(猜测)DESede 带有 CBC 模式和 PKCS#5 填充在这里。请参阅维基百科以了解我在说什么。

这是我

的CryptoRef:

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

由于我使用 CBC 模式和 ccNoPadding,因此无需调用 CCCryptorFinal() 。相反,当我完成一个操作(即完成加密/解密一个文件等)时,我应该调用CCCryptorReset()在下一次操作之前将 CryptoRef 的 iv 重置为初始状态。或者第一个数据块将是缺陷。

感谢您的评论,很抱歉将此问题抛在脑后。我希望这可以帮助遇到同样问题的人。

最新更新