加密 - 解密有什么问题?

时间:2012-06-29 13:17:25

标签: php ios cocoa-touch encryption aes

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

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

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

在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 Domain=net.robnapier.RNCryptManager Code=2 "Unknown header" UserInfo=0x8582e10 {NSLocalizedDescription=Unknown header}

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

在加密器中,它是抛出错误的地方:

  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;

}

这有什么问题?

3 个答案:

答案 0 :(得分:2)

刚刚阅读RNCryptor的网站,我相信它是一个完整的消息输入输出加密器。如果你看看他们的维基上的数据格式

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

我相信他们预计你的数据到ENCRYPT没有标题,但是如果你正在解密,那么它希望数据是用加密器加密的,加密器会添加标题和hmac。

如果我是正确的,那么服务器端放在一起的数据就是RNCryptor希望看到的完整消息的密文部分!!!

答案 1 :(得分:2)

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

答案 2 :(得分:0)

您是否从这里关注了phpiOS个库:

https://github.com/RNCryptor

我的要求是一样的。加密数据到达我的iOS设备,目标c必须解密它。

今天几乎所有的头发拉了之后,我现在能够做到。以下是一段代码:

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

如果您从encrypt.php示例(php内)下载并运行RNCryptor-php-master > examples > encrypt.php,您将收到上面的base64字符串(NSString *message)。它的密码是myPassword。运行此obj c代码将返回此

  

“这是我的测试向量。它不是太长,但不仅仅是一个块而且   需要填充。“

此行正确,源代码为encrypt.php。我正在做的错误是,我正在直接将NSString转换为NSData,如下所示

  

NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];

在我解码了base64字符串之后解密工作

  

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

就是这样。希望它有所帮助。