使用CFB8进行3DES加密,iOS中没有填充?

时间:2014-01-27 10:55:06

标签: ios objective-c encryption 3des commoncrypto

我正在开发一个将加密数据发送到服务器的应用程序。服务器使用带有CFB8的3des并且没有填充。我已经在stackoverflow中阅读了大部分相关问题,但仍然无法使其工作。已经工作了几天但仍无法使其与服务器加密相匹配。这是我试过的 -

 + (NSString*) doCipher:(NSString*)plainText operation:(CCOperation)encryptOrDecrypt {

        const void *vplainText;
        NSData* plainTextData;
        size_t plainTextBufferSize;

        if (encryptOrDecrypt == kCCDecrypt)
        {
           NSData *EncryptData =[NSData  dataWithBase64EncodedString:plainText];
        plainTextBufferSize = [EncryptData length];
        vplainText = [EncryptData bytes];
        }
        else
        {
             plainTextData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        plainTextBufferSize = [plainTextData length];
        }

        CCCryptorStatus ccStatus;
        uint8_t *bufferPtr = NULL;
        size_t bufferPtrSize = 0;
        size_t movedBytes = 0;
         uint8_t iv[kCCBlockSize3DES];

        bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
        bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
        memset((void *)bufferPtr, 0x0, bufferPtrSize);
         memset((void *) iv, 0x0, (size_t) sizeof(iv));

        const void *vkey = kPrivateKey;
        unsigned char IV[8]={0,0,0,0,0,0,0,0};

        ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       0,
                       [keyData bytes],
                       [key length],
                       IV,
                       [plainTextData bytes],
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);

        if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
        else if (ccStatus == kCCParamError) return @"PARAM ERROR";
        else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
        else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
        else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
        else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
        else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";

        NSString *result;

        if (encryptOrDecrypt == kCCDecrypt)
        {
            result = [[NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSASCIIStringEncoding];
        }
        else
        {
            NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
            result = [myData base64EncodedString];
        }

        return result;
    }

似乎CCOptions目前支持kCCOptionPKCS7PaddingkCCOptionECBMode。如何使用CFB8实现3des并且没有填充。任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:2)

编辑:对不起;我之前忽略了一个关键点。你永远不会要求CFB8模式。默认为CBC模式。

您无法使用CCCrypt()。您必须使用CCCryptorCreateWithMode()才能通过该模式。然后使用数据CCCryptorUpdate()CCCryptorFinal()来完成。


如果您不想填充,为什么要请求填充?删除kCCOptionPKCS7Padding。如果你不想要任何选项(你看起来没有),只需传递0。

CFB-8采用初始化向量。你已将它设置为全0。这是服务器使用的吗? (这是一个非常差的IV; CFB的IV应该是随机的,而不是固定的。)

这些行是危险的:

    plainTextBufferSize = [plainText length];
    vplainText = (const void *) [plainText UTF8String];

这将截断任何多字节字符串。更好的解决方案是创建NSData

plainTextData = [self.plainText dataUsingEncoding:NSUTF8StringEncoding];

然后,您可以在bytes上使用lengthplainTextData