我们如何通过Objective C中的DES / CBC / NOPADDING加密字节?

时间:2015-05-29 06:55:18

标签: ios iphone security encryption

我试图通过DES / CBS / NOPADDING算法加密字节数据但无法获得正确的输出。我在下面的代码中给出了我所尝试的内容。请看一下并建议。

#import "STEncryptViewController.h"
#import <CommonCrypto/CommonCryptor.h>
#import "STEncryptorDES.h"
#import "NSData+Base64.h"
#import <CommonCrypto/CommonDigest.h>

#define KEY  @"MY_TEST_KEY"

@interface STEncryptViewController ()

@end


@implementation STEncryptViewController

@synthesize message;
@synthesize encrypted;
@synthesize decrypted;
@synthesize key;
@synthesize outputMessage;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (IBAction)encrypt:(id)sender
{
    const unsigned char bytes[] = {65,17,17,17,17,17,17,17};


    NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];

    NSString *str = self.key.text;
    NSData* data12 = [str dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger len = str.length;
    uint8_t *bytes1 = (uint8_t *)[data12 bytes];
    NSMutableString *result = [NSMutableString stringWithCapacity:len * 3];
    // [result appendString:@"["];

    //Key convertion
    int i = 0;
    while(i < len){
        if (i) {
            [result appendString:@","];
        }
        [result appendFormat:@"%d", bytes1[i]];
        i++;
    }
    // [result appendString:@"]"];
      NSLog (@"String is %@",str);
      NSLog (@"Byte array is %@",result);

    //

    Byte iv1 [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    Byte iv [] = {1, 35, 69, 103, -119, -85, -51, -17};
    NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];

    NSData *encryptedData = [STEncryptorDES encryptData1:data key:[NSData dataWithBytes:iv1 length:sizeof(iv1)] iv:ivData];

    NSLog(@"encrypted : %@", [encryptedData base64EncodedString]);
    self.outputMessage.text = [NSString stringWithFormat:@"Encrypted String ::>> %@",[encryptedData base64EncodedString]];

    [self doCipher:nil enc:kCCEncrypt];
}
- (NSData *)md5DataFromString:(NSString *)input
{
    const char *cStr = [input UTF8String];
    unsigned char digest[16];
    CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call

    return [NSData dataWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
}
- (IBAction)decrypt:(id)sender
{
    NSData *valueData = [self hexToBytes:self.decrypted.text];
    NSData *keyData = [self md5DataFromString:self.key.text];
    Byte iv [] = {1, 35, 69, 103, -119, -85, -51, -17};
    NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
    NSData *decryptedData = [STEncryptorDES decryptData:valueData key:keyData iv:ivData];
    NSLog(@"decrypted : %@", [[NSString alloc] initWithData:decryptedData encoding:NSASCIIStringEncoding]);
    self.outputMessage.text = [NSString stringWithFormat:@"Decrypted String ::>> %@", [[NSString alloc] initWithData:decryptedData encoding:NSASCIIStringEncoding]];
}

- (NSString*)doCipher:(NSString*)plainText enc:(CCOperation)encryptOrDecrypt{

    NSData *key123 = [self hexToBytes:@"MY_TEST_KEY"];
    const void *vplainText;
    size_t plainTextBufferSize;

    if (encryptOrDecrypt == kCCDecrypt)
    {
        NSData *EncryptData = [self hexToBytes:@"5454545454545454"];

      //  NSData *EncryptData =[NSData  dataWithBase64EncodedString:plainText];
        plainTextBufferSize = [EncryptData length];
        vplainText = [EncryptData bytes];
    }
    else
    {
        plainTextBufferSize = [plainText length];
        vplainText = (const void *) [plainText UTF8String];
    }


    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);

    unsigned char cKey[FBENCRYPT_KEY_SIZE];
    bzero(cKey, sizeof(cKey));
    [key123 getBytes:cKey length:FBENCRYPT_KEY_SIZE];


    //unsigned char result1[24]= {0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,00,00,00,00,0};
    unsigned char IV3[8]={1, 35, 69, 103, -119, -85, -51, -17};

    uint8_t iv[kCCBlockSize3DES];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));

    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       0x0000 ,
                       cKey, //"123456789012345678901234", //key
                       kCCKeySize3DES,
                       IV3 ,  //iv,
                       vplainText,  //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];

    }
    else
    {
        NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        NSLog(@"data is: %@", myData);
      //  result = [NSData base64StringFromData:myData length:myData.length];
        //  result = [[NSString alloc]initWithData:myData encoding:NSUTF8StringEncoding];

        result = nil;
    }


    return result;
}

-(NSData*)hexToBytes:(NSString *)hex {


    NSString *safeStr = [hex stringByReplacingOccurrencesOfString:@"0" withString:@"A"];

    NSMutableData* data = [NSMutableData data];
    int idx;
    for (idx = 0; idx+2 <= safeStr.length; idx+=2) {
        NSRange range = NSMakeRange(idx, 2);
        NSString* hexStr = [safeStr substringWithRange:range];
        NSScanner* scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    }

    NSLog(@"%lu",(unsigned long)data.hash);

    return data;
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

这是我的全部努力。目前它正在工作,但没有预期的输出。请建议我在这里缺少什么?

2 个答案:

答案 0 :(得分:0)

一个明显的错误是使用了STEncryptorDES并指定了填充,但问题是应该使用填充。

观察:
- 您使用nil调用doCipher并且不使用它的返回值,从问题中删除不需要/未使用的代码。
- 执行相当简单的操作有很多代码 - 似乎测试数据变量名为iv1,如果正确则使用更好的名称 - DES不应该用于新工作,只有在必要时才能与现有工作互操作,它不是很安全。新工作应使用AES - 好几年都没有需要@synthesize

答案 1 :(得分:-1)

在密码学&#34; DESede / CBC / NoPadding&#34;使用以下代码可能对您有所帮助。

Byte iv [] = {1, 35, 69, 103, -119, -85, -51, -17};

NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];

NSData key = ["MY_TEST_KEY" dataUsingEncoding:NSUTF8StringEncoding]

char cKey[key.length];
bzero(cKey, sizeof(cKey));
[key getBytes:cKey length:key.length];

// setup iv
char cIv[kCCBlockSizeDES];
bzero(cIv, kCCBlockSizeDES);
if (ivData) {
    [ivData getBytes:cIv length:kCCBlockSizeDES];
}

// setup output buffer
size_t bufferSize = [data length] + kCCBlockSizeDES;
void *buffer = malloc(bufferSize);

// do encrypt
size_t encryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                      kCCAlgorithm3DES,
                                      ccNoPadding,
                                      cKey,
                                      key.length,
                                      cIv,
                                      [data bytes],
                                      [data length],
                                      buffer,
                                      bufferSize,
                                      &encryptedSize);

if (cryptStatus == kCCSuccess) {

    resultData = [NSData dataWithBytes:buffer length:encryptedSize];
    free(buffer);

} else {
    free(buffer);
    NSLog(@"[ERROR] failed to encrypt|CCCryptoStatus: %d", cryptStatus);

    return nil;
}