1

在服务器端在 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

在 encryptor 中,这是引发错误的地方:

  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;

}

这有什么问题?

4

3 回答 3

2

刚刚阅读了 RNCryptor 的站点,我相信它是一个完整的消息输入输出加密器。如果您查看他们 wiki 上的数据格式

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

我相信他们希望您加密的数据没有标头,但如果您正在解密,那么它预计数据是使用他们的加密器加密的,它添加了标头和 hmac。

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

于 2012-06-29T13:33:35.923 回答
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;
}
于 2013-12-11T10:07:31.180 回答
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。我做的错误是,我直接转换NSStringNSData如下

NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding];

在我像下面这样解码该base64字符串后,解密工作

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

就是这样。希望能帮助到你。

于 2015-09-10T12:56:59.217 回答