简体   繁体   中英

What is wrong in encryption-decryption?

Encrypting data in php on server side and decrypting in iOS fails.

On server in php it looks like this(just for test):

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, "a16byteslongkey!a16byteslongkey!", "iphone", MCRYPT_MODE_CBC, $iv);
$base64encoded_ciphertext = base64_encode($ciphertext);
return $base64encoded_ciphertext;

In iOS:

 NSData *decrypted = [[RNCryptor AES256Cryptor] decryptData:[QSStrings decodeBase64WithString: text] password:@"a16byteslongkey!a16byteslongkey!" error:&error];

NSLog(@"errro - %@", [error description]);

NSString *decryptedString = [[[NSString alloc] initWithData: decrypted encoding: NSUTF8StringEncoding] autorelease];

Error description is:

Error Domain=net.robnapier.RNCryptManager Code=2 "Unknown header" UserInfo=0x8582e10 {NSLocalizedDescription=Unknown header}

Using RNCryptor: https://github.com/rnapier/RNCryptor

in encryptor that is the place where error is thrown:

  if (![header isEqualToData:[NSData dataWithBytes:AES128CryptorHeader length:sizeof(AES128CryptorHeader)]]) {
*error = [NSError errorWithDomain:kRNCryptorErrorDomain code:kRNCryptorUnknownHeader
                         userInfo:[NSDictionary dictionaryWithObject:NSLocalizedString(@"Unknown header", @"Unknown header") forKey:NSLocalizedDescriptionKey]];
return NO;

}

What is wrong whith this?

Just reading the site for RNCryptor, I believe it is a full message input output encryptor. If you look at the data format on their wiki

https://github.com/rnapier/RNCryptor/wiki/Data-Format

I believe that they EXPECT that your data to ENCRYPT does NOT have a header, but if you are DECRYPTING, then it expects that the data was encrypted using their encryptor, which adds header and hmac.

If I'm correct, the data that your server side puts together is simply the cipher-text portion of the full message that RNCryptor expects to see!!!

//After getting data from server 
-(Void)getDataFromServer:(NSData*)responseData
{
 NSString *base64String = [responseData base64EncodedStringWithOptions:0];

//Decode base64 data
    NSData *decodedData = [DatabaseHandler base64DataFromString:newStr];

    NSData *decryptedData = [RNDecryptor decryptData:decodedData withSettings:kRNCryptorAES256Settings password:@"YourKey" error:&error];

        NSLog(@"%@",[error userInfo]);
         NSString *dataToDecrypt=  [decryptedData base64EncodedStringWithOptions:0];

    NSString* newStr = [[NSString alloc] initWithData:decryptedData
                                             encoding:NSUTF8StringEncoding]; 
}

- (NSString *) base64StringFromData: (NSData *)data length: (int)length {
  unsigned long ixtext, lentext;
  long ctremaining;
  unsigned char input[3], output[4];
  short i, charsonline = 0, ctcopy;
  const unsigned char *raw;
  NSMutableString *result;

  lentext = [data length]; 
  if (lentext < 1)
    return @"";
  result = [NSMutableString stringWithCapacity: lentext];
  raw = [data bytes];
  ixtext = 0; 

  while (true) {
    ctremaining = lentext - ixtext;
    if (ctremaining <= 0) 
       break;        
    for (i = 0; i < 3; i++) { 
       unsigned long ix = ixtext + i;
       if (ix < lentext)
          input[i] = raw[ix];
       else
  input[i] = 0;
  }
  output[0] = (input[0] & 0xFC) >> 2;
  output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
  output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
  output[3] = input[2] & 0x3F;
  ctcopy = 4;
  switch (ctremaining) {
    case 1: 
      ctcopy = 2; 
      break;
    case 2: 
      ctcopy = 3; 
      break;
  }

  for (i = 0; i < ctcopy; i++)
     [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];

  for (i = ctcopy; i < 4; i++)
     [result appendString: @"="];

  ixtext += 3;
  charsonline += 4;

  if ((length > 0) && (charsonline >= length))
    charsonline = 0;
  }     
  return result;
}

Did you follow php and iOS libraries from here:

https://github.com/RNCryptor

My requirement was same. Encrypted data reached my iOS device and objective c has to decrypt it.

After pulling almost all my hairs today, I am able to make it now. Here is a snippet of code below:

NSString *message = @"AwF+ttZCyQ7eurRU2zo4KGqQTLBXRRdmBiYe65uv/3AENxUKf6wo3Cpsh8Yk7/OsOwXRDDR3lO5OKNwhJCSxxUNYbpBwWb2KDSxiRbG+11Vrfbk35VRvelAo2Ai8PAz4FJ9z9u7NdBvyVQYF8v1Pd7/rB4TMXaWd98AM4KO3EYmLhTxMpbqDu1LJXDT4TDgXsjv7/ISnISQK3oTmG1vYlO7N";
NSString *password = @"myPassword";

NSData *data = [[NSData alloc] initWithBase64EncodedString:message options:0];
NSError *error;
NSData *decryptedData = [RNDecryptor decryptData:data
                                    withPassword:password
                                           error:&error];

NSString* newStr = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
NSLog(@"\n\nerror: %@\n\nString:%@", error, newStr);

If you download and run encrypt.php from their php sample (inside RNCryptor-php-master > examples > encrypt.php ) you will receive that base64 string above ( NSString *message ). Its password is myPassword there. And running this obj c code will return you this👇

"Here is my test vector. It's not too long, but more than a block and needs padding."

This line 👆is right there is source code of encrypt.php . The mistake I was doing was, I was converting NSString to NSData directly like below👇

NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];

the decryption worked after I decoded that base64 string like below👇

NSData *data = [[NSData alloc] initWithBase64EncodedString:message options:0];

thats it. Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM