1

最近我正在实现一个使用 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,这似乎是徒劳的。

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

4

2 回答 2

0

Here is my CryptoRef:

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

Since I use CBC mode and ccNoPadding, there is no need to call CCCryptorFinal(). Instead, when I finish one operation (i.e. finish encrypt/decrypt one file, etc.), I should call CCCryptorReset() to reset the CryptoRef's iv to initial state before next operation. Or the first block of data will be defect.

Thanks for comments and sorry for left this issue behind. I hope this could help people who encountered the same problem.

于 2012-05-15T01:52:54.207 回答
0

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

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

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

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

于 2012-05-08T21:03:38.783 回答