iOS 中的 3DES 加密似乎没有加密最后一个块

3DES encryption in iOS does not seem to encrypt last block

我在objective-c

中有以下代码
NSString* v_plainText = @"1234567890123456789012345678";
NSString* plainText = (const void *) [v_plainText UTF8String];

size_t plainTextBufferSize = [v_plainText length];

size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
size_t movedBytes = 0;
uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));

Byte iv[8] = {0,0,0,0,0,0,0,0};

NSString *key = (const void *) [@"12345678ABCDEFGH!@#$%^&*" UTF8String];

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding & kCCModeCBC,
                   key,
                   kCCKeySize3DES,
                   iv,
                   plainText,
                   plainTextBufferSize,
                   (void *)bufferPtr, // output
                   bufferPtrSize,
                   &movedBytes);

NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
NSString* str = [result base64EncodedStringWithOptions:0];

结果如下:

geHFnvoept2aKiruo6InSvc7WVPdHNq2

当我在 .NET 中 运行 模拟代码时,它给了我这个结果:

geHFnvoept2aKiruo6InSvc7WVPdHNq2TENQX5q9Beg=

出于某种原因,objective-c 版本只有 returns 24 个字节,而输入是 28 个字节。我希望它像 .NET 版本一样是 32 字节。我无法确定我在这里做错了什么。

加密错误为:

kCCOptionPKCS7Padding & kCCModeCBC,

您需要 |,而不是 &,但是 kCCModeCBC 不是一个有效的选项,不需要任何选项,因为 CBC 是默认模式,您只需要:

kCCOptionPKCS7Padding,

不幸的是还有其他objectiveC编码错误,主要是:

NSString* plainText = (const void *) [v_plainText UTF8String];
NSString *key = (const void *) [@"12345678ABCDEFGH!@#$%^&*" UTF8String];

改为使用:

NSData* plainText = [v_plainText dataUsingEncoding:NSUTF8StringEncoding];
NSData *key = [@"12345678ABCDEFGH!@#$%^&*" dataUsingEncoding:NSUTF8StringEncoding];

下面是转换为使用 NSData 的完整代码:

NSString* plainText = @"1234567890123456789012345678";
NSString* keyText = @"12345678ABCDEFGH!@#$%^&*";

NSData* plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding];
Byte iv[8] = {0,0,0,0,0,0,0,0};
size_t bufferSize = plainData.length + kCCBlockSize3DES;
NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize];
size_t movedBytes = 0;

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding,
                   keyData.bytes,
                   kCCKeySize3DES,
                   iv,
                   plainData.bytes,
                   plainData.length,
                   cypherData.mutableBytes,
                   cypherData.length,
                   &movedBytes);

cypherData.length = movedBytes;
NSString* str = [cypherData base64EncodedStringWithOptions:0];
NSLog(@"str: %@", str);

输出:

str: geHFnvoept2aKiruo6InSvc7WVPdHNq2TENQX5q9Beg=