我在网络各个地方的iPhone上看到了很多关于CCCrypt和3DES的帖子,但似乎没有一个使用ECB模式的例子,总是使用PKCS7Padding。
是否有人使用CCCrypt函数使用3DES和ECB模式加密和解密传递的字符串?
目前我的代码(我承认来自某个网站,我认为这是Apple自己的开发者论坛)如下:
+ (NSString*)doCipher:(NSString*)plainText action:(CCOperation)encryptOrDecrypt {
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt) {
NSData *EncryptData = [[NSData alloc] initWithBase64EncodedString:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else {
//plainTextBufferSize = [plainText length];
//vplainText = (const void *)[plainText UTF8String];
NSData *plainTextData = [plainText dataUsingEncoding: NSUTF8StringEncoding];
plainTextBufferSize = [plainTextData length];
vplainText = [plainTextData bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSString *key = @"123456789012345678901234";
NSString *initVec = @"init Vec";
const void *vkey = (const void *)[key UTF8String];
const void *vinitVec = (const void *)[initVec UTF8String];
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionECBMode,
vkey, //"123456789012345678901234", //key
kCCKeySize3DES,
nil, //"init Vec", //iv,
vplainText, //"Your Name", //plainText,
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] autorelease];
}
else {
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64EncodingWithLineLength:movedBytes];
}
return result; }
上述ALWAYS失败并出现PARAM ERROR。
答案 0 :(得分:2)
- (NSData *) encrypt:(NSString *) dataToEncrypt{
NSUInteger data_length= [dataToEncrypt length];
uint8_t input_raw_data[data_length];
//The [dataToEncrypt length] gives the number of chars present in the string.So say there are 10 chars.
//Now,the getBytes needs to get the raw bytes from this i.e. binary NSData.But suppose the encoding was
//full 16 bit encoding then the number of bytes needed wd have been double- 20.But as we are using the
//NSUTF8StringEncoding,the number of byes needed is 1 per char as the chars(even if originally unicode are
//compressed into an 8 bit UTF8 encoding.)
[dataToEncrypt getBytes:&input_raw_data maxLength:data_length usedLength:NULL encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0,data_length) remainingRange:NULL];
//According to the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t buffer_size = data_length + kCCBlockSizeAES128;
void* buffer = malloc(buffer_size);
size_t num_bytes_encrypted = 0;
CCCryptorStatus crypt_status = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
[self.symmetricKey bytes], kCCKeySizeAES256,
NULL,
input_raw_data, data_length,
buffer, buffer_size,
&num_bytes_encrypted);
NSLog(@"~~num bytes encrypted: %d",num_bytes_encrypted);
if (crypt_status == kCCSuccess){
NSLog(@"~~Data encoded successfully...");
return [NSData dataWithBytesNoCopy:buffer length:num_bytes_encrypted];
}
free(buffer); //free the buffer;
return nil;
}
- (NSData *) decrypt:(NSData *) dataToDecrypt{
NSUInteger data_length= [dataToDecrypt length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t buffer_size = data_length + kCCBlockSizeAES128;
void* buffer = malloc(buffer_size);
size_t num_bytes_decrypted = 0;
CCCryptorStatus crypt_status = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
[self.symmetricKey bytes], kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[dataToDecrypt bytes], data_length, /* input */
buffer, buffer_size, /* output */
&num_bytes_decrypted);
NSLog(@"~~num bytes decrypted: %d",num_bytes_decrypted);
if (crypt_status == kCCSuccess){
NSLog(@"~~Data decoded successfully...");
return [NSData dataWithBytesNoCopy:buffer length:num_bytes_decrypted];
}
free(buffer); //free the buffer;
return nil;
}
答案 1 :(得分:1)
上面的代码对我有用,但有一些变化。这些变化是我将moveBytes和bufferPtf作为实例变量进行了decelare并跟随chandge。
if (encryptOrDecrypt == kCCDecrypt) {
plainTextBufferSize = movedBytes;
vplainText = bufferPtr;
}
else {
plainTextBufferSize = [plainText length];
vplainText = (const void *)[plainText UTF8String];
}
而是base64encoding使用nsasciiencoding。