CCCrypt 解码的明文长度错误

Posted

技术标签:

【中文标题】CCCrypt 解码的明文长度错误【英文标题】:Plaintext decoded by CCCrypt has wrong length 【发布时间】:2012-04-14 07:59:00 【问题描述】:

最近,我正在使用 CCCrypt 来实现一些自定义的加密算法。但是,当我使用 CCCryptorUpdate 解密密文时,输出总是比原始纯文本少 8 个字节。以下是我的代码:

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

    CCCryptorStatus cryptStatus;
    int iBytesRead = 0;

    while ( (iBytesRead = [strmSrc read:inputBuf maxLength:BlockSize]) > 0 ) 
    
        NSLog(@"Bytes read from plain buffer: %d", iBytesRead);
        [Util FillBuffer:inputBuf Length:BlockSize Current:iBytesRead];

        cryptStatus = CCCryptorUpdate(tdesCrypto, &inputBuf, BlockSize, &outputBuf, BlockSize, &dataOutMoved);
        assert(dataOutMoved<=BlockSize && cryptStatus==noErr);
        NSLog(@"EncDataOutMoved: %ld", dataOutMoved);
        [Util FillBuffer:outputBuf Length:BlockSize Current:dataOutMoved];
        [strmDest write:outputBuf maxLength:BlockSize];
    


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

    CCCryptorStatus cryptStatus;
    int iBytesRead = 0;

    while ( (iBytesRead = [strmSrc read:inputBuf maxLength:BlockSize]) > 0 ) 
    
        NSLog(@"Bytes read from cipher buffer: %d", iBytesRead);
        cryptStatus = CCCryptorUpdate(tdesCrypto, &inputBuf, BlockSize, &outputBuf, BlockSize+kCCBlockSize3DES, &dataOutMoved);
        NSLog(@"Lengh needed: %zu", CCCryptorGetOutputLength(tdesCrypto, BlockSize, YES));
        NSLog(@"DecDataOutMoved: %ld", dataOutMoved);
        assert(dataOutMoved<=BlockSize && cryptStatus==noErr);
        [strmDest write:outputBuf maxLength:dataOutMoved];
    



I encrypted 3 buffer of 4096. When decrypting them, the log shows that the size of 1st decrypted data is 4088, BUT! The missing data is actually in the begining of the 2nd decrypted data. 

2012-04-14 15:17:41.929 otest[25168:7803] Bytes read from cipher buffer: 4096
2012-04-14 15:17:41.929 otest[25168:7803] Lengh needed: 4104
2012-04-14 15:17:41.930 otest[25168:7803] DecDataOutMoved: 4088
end of 1st block:<..d71eaf27 affc4c8c b1c54afa c5434397 ebc17a49>

2012-04-14 15:17:45.291 otest[25168:7803] Bytes read from cipher buffer: 4096
2012-04-14 15:17:45.292 otest[25168:7803] Lengh needed: 4104
2012-04-14 15:17:45.293 otest[25168:7803] DecDataOutMoved: 4096
begining of 2nd block <**86b61bce b4342728** 88240a64 837327d4 0bb572a2 f5220928

请注意,86b61bce b4342728 位于加密前第一个块的末尾。

我还检查了第一个块的开头,我确信我没有弄乱数据范围。似乎数据已解密,但直到下一次操作才检索到它们。

我想在每个加密/解密操作中获得一个完整的块,但我不想使用 CCCrypt 函数,因为我必须将 Key 和 Iv 位都传递给它。我只是想把CCCryptorRef传给它,比较简单。

休伯特

【问题讨论】:

如果您想使用 CCCryptorRef 或其他任何东西都可以,但请指明您使用的是哪种密码(密码块模式和填充),例如通过展示您如何创建CCCryptorRef。猜测很有趣,但你可能会得到猜测的答案:) 【参考方案1】:

您需要调用CCCryptFinal完成加解密。这将负责添加/删除填充。

【讨论】:

【参考方案2】:

我使用 CCCrypt 函数对某些东西进行 DES 加密。当要加密的数据长度不是 8 Byte 的倍数时,就会出现错误大小。

所以我处理如下:

- (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key

    NSString *ciphertext = nil;
    const char *textBytes = [plainText UTF8String];
    NSUInteger dataLength = [plainText length];
    NSUInteger len1=dataLength % 8;

    if(len1!=0)
    
        dataLength+=(8-len1);
        
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;

    Byte iv[] = 0x02, 0x00, 0x01, 0x02, 0x00, 0x06, 0x00, 0x05;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                          NULL,
                                          [key UTF8String], kCCKeySizeDES,
                                          iv,
                                          textBytes, dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
.....

然后一切正常!

【讨论】:

其实关键是我重用了crypt引用,没有完成。看来我离开这个话题太久了。无论如何,谢谢你的回答:) 很抱歉浪费你的时间。

以上是关于CCCrypt 解码的明文长度错误的主要内容,如果未能解决你的问题,请参考以下文章

CCCrypt 不适用于 iOS 7 的 xcode 5

Kotlin Native (iOS),使用 CValuesRef 和 CCCrypt

Obj-C:在 CommonCrypto 中,如果 CCCrypt() 不使用选项 kCCOptionPKCS7Padding,则结果缓冲区为空

在obj-c中将NSData加密为NSString?

在obj-c中加密NSData到NSString?

AES128_CBC_NoPading加密、sha256withRSA签名