代码之家  ›  专栏  ›  技术社区  ›  user3437050

使用3des ios7加密nsstring

  •  1
  • user3437050  · 技术社区  · 11 年前

    我是iOS7开发和目标c的新手,我需要开发一个应用程序,它将使用3DES向服务器发送加密数据。我在堆栈溢出和Net中进行了搜索,但仍然无法正常工作。最后我尝试了这段代码,但结果为空,

    + (NSString*)encrypt:(NSString*)plainText withKey:(NSString*)key{
        uint8_t keyByte[kSecrectKeyLength];
    
        NSMutableData *keyData = [[NSMutableData alloc] init];
        int i;
        for (i=0; i < [key length] / 2; i++) {
            NSString *tempNumber = [key substringWithRange: NSMakeRange(i * 2, 2)];
            NSScanner *scanner=[NSScanner scannerWithString:tempNumber];
            unsigned int temp;
            [scanner scanHexInt:&temp];
            Byte B = (Byte)(0xFF & temp);
            keyByte[i] = B;
        }
    
        NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        size_t plainTextBufferSize = [data length];
        const void *vplainText = (const void *)[data bytes];
    
        CCCryptorStatus ccStatus;
        uint8_t *bufferPtr = NULL;
        size_t bufferPtrSize = 0;
        size_t movedBytes = 0;
    
        bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
        bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
        memset((void *)bufferPtr, 0x0, bufferPtrSize);
    
        const void *vkey = (const void *) keyByte;
        const void *vinitVec = (const void *) [gIv UTF8String];
    
        ccStatus = CCCrypt(kCCEncrypt,
                           kCCAlgorithm3DES,
                           kCCOptionPKCS7Padding,
                           vkey,
                           kCCKeySize3DES,
                           vinitVec,
                           vplainText,
                           plainTextBufferSize,
                           (void *)bufferPtr,
                           bufferPtrSize,
                           &movedBytes);
    
        NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        //NSString *result = [GTMBase64 stringByEncodingData:myData];
        NSString *result = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
    
        NSLog(@"result=%@",result);
    
        return result;
    }
    

    请你对解决方案有什么想法???

    1 回复  |  直到 11 年前
        1
  •  5
  •   Fonix    11 年前

    lol前几天我自己也遇到了这个问题,现在我有了一个有效的解决方案,使用这个代码

    + (NSData *)tripleDesEncryptString:(NSString *)input
                                   key:(NSString *)key
                                 error:(NSError **)error
    {
    NSParameterAssert(input);
    NSParameterAssert(key);
    
    NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t outLength;
    
    NSAssert(keyData.length == kCCKeySize3DES, @"the keyData is an invalid size");
    
    NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  +  kCCBlockSize3DES)];
    
    CCCryptorStatus
    result = CCCrypt(kCCEncrypt, // operation
                     kCCAlgorithm3DES, // Algorithm
                     kCCOptionPKCS7Padding | kCCOptionECBMode, // options
                     keyData.bytes, // key
                     keyData.length, // keylength
                     nil,// iv
                     inputData.bytes, // dataIn
                     inputData.length, // dataInLength,
                     outputData.mutableBytes, // dataOut
                     outputData.length, // dataOutAvailable
                     &outLength); // dataOutMoved
    
    if (result != kCCSuccess) {
        if (error != NULL) {
            *error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name."
                                         code:result
                                     userInfo:nil];
        }
        return nil;
    }
    [outputData setLength:outLength];
    return outputData;
    }
    
    
    
    + (NSString *)tripleDesDecryptData:(NSData *)input
                                   key:(NSString *)key
                                 error:(NSError **)error
    {
    NSParameterAssert(input);
    NSParameterAssert(key);
    
    NSData *inputData = input;
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t outLength;
    
    NSAssert(keyData.length == kCCKeySize3DES, @"the keyData is an invalid size");
    
    NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  +  kCCBlockSize3DES)];
    
    CCCryptorStatus
    result = CCCrypt(kCCDecrypt, // operation
                     kCCAlgorithm3DES, // Algorithm
                     kCCOptionPKCS7Padding | kCCOptionECBMode, // options
                     keyData.bytes, // key
                     keyData.length, // keylength
                     nil,// iv
                     inputData.bytes, // dataIn
                     inputData.length, // dataInLength,
                     outputData.mutableBytes, // dataOut
                     outputData.length, // dataOutAvailable
                     &outLength); // dataOutMoved
    
    if (result != kCCSuccess) {
        if (error != NULL) {
            *error = [NSError errorWithDomain:@"com.your_domain.your_project_name.your_class_name."
                                         code:result
                                     userInfo:nil];
        }
        return nil;
    }
    [outputData setLength:outLength];
    return [[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding];
    }
    

    您可能希望对加密方法产生的数据进行base64编码,然后对任何您想要解密的数据进行反base64编码。NSData现在有内置的方法来实现这一点,例如:

    [data base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)];
    

    为了测试这些函数是否有效,我使用了这个测试函数

    + (void) testEncryptionAndDecryption {
    
        NSData *encrypted = [self tripleDesEncryptString:@"test" key:@"123456789123456789123456" error:nil];
        NSLog(@"encrypted data length: %lu", (unsigned long)encrypted.length);
        NSString *decrypted = [self tripleDesDecryptData:encrypted key:@"123456789123456789123456" error:nil];
        NSLog(@"decrypted text: %@", decrypted);
    }
    

    这给了我你所期望的正确输出