3

我试图在 iOS 上实现一种加密方式。匹配在 JAVA 上运行的那个。

但我尝试的每一件事都会导致不同的加密模式

这是我用于加密的 Java 代码:

  public static String encrypt(String plaintext)
    throws Exception
  {
    Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
    byte[] encrypted = c.doFinal(plaintext.getBytes("UTF-8"));
    return Base64.encode(encrypted);
  }

有什么简单的方法可以在目标 c 中使用 DESede/CBC/PKCS5Padding 吗?

这是我正在使用的代码,但它给出了不同的结果

+ (NSString*) doCipher:(NSString*)plainText:(CCOperation)encryptOrDecrypt {

    const void *vplainText;
    size_t plainTextBufferSize;

    if (encryptOrDecrypt == kCCDecrypt)
    {
       // NSData *EncryptData = [NSData dataWithBase64EncodedString:plainText];
       // plainTextBufferSize = [EncryptData length];
       // vplainText = [EncryptData bytes];
    }
    else
    {
        NSData *tempData = [plainText dataUsingEncoding:NSASCIIStringEncoding];
        plainTextBufferSize = [tempData length];
        vplainText =  [tempData 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);


    //my shared key i changed to Zeros 
    NSMutableData *payload = [[NSMutableData alloc] init];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
        [payload appendBytes:"00" length:1];
     [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];
    [payload appendBytes:"00" length:1];

    NSString *key = [[NSString alloc]initWithData:payload encoding:NSUTF8StringEncoding];

//my iV i changed it to zeros 
    NSMutableData *IV = [[NSMutableData alloc] init];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];
    [IV appendBytes:"00" length:1];

    NSLog(@"key byte is %s", [payload bytes]);
     NSLog(@"IV byte is %s", [IV bytes]);
    // Initialization vector; dummy in this case 0's.
    uint8_t iv[kCCBlockSize3DES];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));

    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding,
                       (const void *)[payload bytes], //"123456789012345678901234", //key
                       kCCKeySize3DES,
                       [IV bytes],  //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]];
        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 = [myData base64EncodedString];
      //  result = [[NSString alloc]initWithData:myData encoding:NSUTF8StringEncoding];
    }
    return result;
}
4

2 回答 2

3

@owlstead 感谢您的提示,

我真的检查了每一件事,你是对的,问题出在输入上

所以这是输入输入的正确方法:

  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]={0,0,0,0,0,0,0,0};

当然,您必须将数字更改为您自己的 key 和 IV 。

完整代码:只需将 IV 和结果更改为您的数据 :)

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

    const void *vplainText;
    size_t plainTextBufferSize;





    if (encryptOrDecrypt == kCCDecrypt)
    {
        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 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]={0,0,0,0,0,0,0,0};

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

    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding ,
                       result1, //"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];
    }
    return result;
}
于 2013-06-02T08:36:27.760 回答
1

更新瓦利德的答案

关键和 IV 可以是:

const unsigned char *keyString = (const unsigned char *)[@"ASAF#Key$M0BiLE!WS@DG_1@"  cStringUsingEncoding: NSUTF8StringEncoding];
const unsigned char *initializeVactorString = (const unsigned char *)[@"ASAF@DG#" cStringUsingEncoding: NSUTF8StringEncoding];

完整的方法是:

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

const void *vplainText;
size_t plainTextBufferSize;

if (encryptOrDecrypt == kCCDecrypt)
{
    NSString *base64EncodedString = [[plainText dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
    NSData *encryptData = [[NSData alloc]initWithBase64EncodedString:base64EncodedString options:0];
    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;

bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);

const unsigned char *keyString = (const unsigned char *)[@"ASAF#Key$M0BiLE!WS@DG_1@"  cStringUsingEncoding: NSUTF8StringEncoding];
const unsigned char *initializeVactorString = (const unsigned char *)[@"ASAF@DG#" cStringUsingEncoding: NSUTF8StringEncoding];

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

ccStatus = CCCrypt(encryptOrDecrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding,
                   keyString,
                   kCCKeySize3DES,
                   initializeVactorString,
                   vplainText,
                   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];
    result = [myData base64EncodedStringWithOptions:0];
}
NSLog(@"%@",result);
return result   ;

}

有时服务器需要十六进制转换,这是将字符串转换为十六进制的方法

+ (NSString *) stringToHex:(NSString *)str{

       NSUInteger len = [str length];
       unichar *chars = malloc(len * sizeof(unichar));
       [str getCharacters:chars];

       NSMutableString *hexString = [[NSMutableString alloc] init];

       for(NSUInteger i = 0; i < len; i++ )
       {
          [hexString appendString:[NSString stringWithFormat:@"%x", chars[i]]];
       }
       free(chars);

       return hexString ;
 }

+ (NSString *) stringFromHex:(NSString *)str{

     NSMutableData *stringData = [[NSMutableData alloc] init];
     unsigned char whole_byte;
     char byte_chars[3] = {'\0','\0','\0'};
     int i;
     for (i=0; i < [str length] / 2; i++) {
        byte_chars[0] = [str characterAtIndex:i*2];
        byte_chars[1] = [str characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [stringData appendBytes:&whole_byte length:1];
      }
      return [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding];
}
于 2015-03-10T07:26:07.927 回答