加密 - 解密有什么问题?

问题描述:

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?

加密服务器端php中的数据并在iOS中解密失败。 p>

在php中的服务器上它看起来像这样(仅用于测试): p>

  $ 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; 
  code  >  pre> 
 
 

在iOS中: p>

  NSData * decrypted = [[RNCryptor AES256Cryptor] decryptData:[QSStrings decodeBase64WithString:text] password:@“  a16byteslongkey!a16byteslongkey!” 错误:& error]; 
 
NSLog(@“errro  - %@”,[错误描述]); 
 
NSString * decryptedString = [[[NSString alloc] initWithData:解密编码:NSUTF8StringEncoding] autorelease]; \  n  code>  pre> 
 
 

错误描述为: p>

 错误Domain = net.robnapier.RNCryptManager Code = 2“Unknown header”UserInfo  = 0x8582e10 {NSLocalizedDescription =未知标题} 
  code>  pre> 
 
 

使用RNCryptor: https://github.com/rnapier/RNCryptor p>

在加密器中,它是引发错误的地方: p>

  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; 
  code>  pre> 
 
 

} p>

Wh 这是错的吗? p> div>

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(@"

error: %@

String:%@", 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