【问题标题】:How can we encrypt bytes through DES/CBC/NOPADDING in Objective C?我们如何在 Objective C 中通过 DES/CBC/NOPADDING 加密字节?
【发布时间】:2015-08-11 22:25:17
【问题描述】:

我正在尝试通过 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

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

【问题讨论】:

  • 以十六进制转储格式添加预期的加密输出,以将明确的输入数据添加到问题中。清理代码以仅显示演示问题所需的代码。

标签: ios iphone security encryption


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    在密码学“DESede/CBC/NoPadding”中,使用以下代码可能会对您有所帮助。

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

    【讨论】:

      猜你喜欢
      • 2020-03-29
      • 1970-01-01
      • 2014-03-21
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多